From ba3247d54b245ed1021a7ba34c04c8f3859ada9e Mon Sep 17 00:00:00 2001 From: Samuel Gomes <47574584+a740g@users.noreply.github.com> Date: Mon, 26 Aug 2024 02:41:35 +0530 Subject: [PATCH 1/3] Use std::hash to generate a proper unique key --- internal/c/parts/audio/audio.cpp | 5 +++-- internal/c/parts/audio/framework.h | 12 +++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/internal/c/parts/audio/audio.cpp b/internal/c/parts/audio/audio.cpp index 63ddf2d7f..b39c24cb0 100644 --- a/internal/c/parts/audio/audio.cpp +++ b/internal/c/parts/audio/audio.cpp @@ -1175,7 +1175,7 @@ struct SoundHandle { ma_uint32 maFlags; // miniaudio flags that were used when initializing the sound ma_decoder_config maDecoderConfig; // miniaudio decoder configuration ma_decoder *maDecoder; // this is used for files that are loaded directly from memory - intptr_t bufferKey; // a key that will uniquely identify the data the decoder will use + uint64_t bufferKey; // a key that will uniquely identify the data the decoder will use ma_audio_buffer_config maAudioBufferConfig; // miniaudio buffer configuration ma_audio_buffer *maAudioBuffer; // this is used for user created audio buffers (memory is managed by miniaudio) RawStream *rawStream; // Raw sample frame queue @@ -1620,7 +1620,8 @@ int32_t func__sndopen(qbs *qbsFileName, qbs *qbsRequirements, int32_t passed) { // Load the file from file or memory based on the requirements string if (fromMemory) { // Configure a miniaudio decoder to load the sound from memory - audioEngine.soundHandles[handle]->bufferKey = (intptr_t)qbsFileName->chr; // make a unique key and save it + audioEngine.soundHandles[handle]->bufferKey = std::hash{}( + std::string_view(reinterpret_cast(qbsFileName->chr), qbsFileName->len)); // make a unique key and save it audioEngine.bufferMap.AddBuffer(qbsFileName->chr, qbsFileName->len, audioEngine.soundHandles[handle]->bufferKey); // make a copy of the buffer auto [buffer, bufferSize] = audioEngine.bufferMap.GetBuffer(audioEngine.soundHandles[handle]->bufferKey); // get the buffer pointer and size audioEngine.maResult = InitializeSoundFromMemory(buffer, bufferSize, handle); // create the ma_sound diff --git a/internal/c/parts/audio/framework.h b/internal/c/parts/audio/framework.h index 37c0d78c6..10f370c16 100644 --- a/internal/c/parts/audio/framework.h +++ b/internal/c/parts/audio/framework.h @@ -24,7 +24,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -68,7 +70,7 @@ class BufferMap { size_t refCount; }; - std::unordered_map buffers; + std::unordered_map buffers; public: // Delete assignment operators @@ -88,7 +90,7 @@ class BufferMap { /// @param size The size of the data /// @param key The unique key that should be used /// @return True if successful - bool AddBuffer(const void *data, size_t size, intptr_t key) { + bool AddBuffer(const void *data, size_t size, uint64_t key) { if (data && size && key && buffers.find(key) == buffers.end()) { Buffer buf = {}; @@ -111,7 +113,7 @@ class BufferMap { /// @brief Increments the buffer reference count /// @param key The unique key for the buffer - void AddRef(intptr_t key) { + void AddRef(uint64_t key) { const auto it = buffers.find(key); if (it != buffers.end()) { auto &buf = it->second; @@ -124,7 +126,7 @@ class BufferMap { /// @brief Decrements the buffer reference count and frees the buffer if the reference count reaches zero /// @param key The unique key for the buffer - void Release(intptr_t key) { + void Release(uint64_t key) { const auto it = buffers.find(key); if (it != buffers.end()) { auto &buf = it->second; @@ -144,7 +146,7 @@ class BufferMap { /// @brief Gets the raw pointer and size of the buffer with the given key /// @param key The unique key for the buffer /// @return An std::pair of the buffer raw pointer and size - std::pair GetBuffer(intptr_t key) const { + std::pair GetBuffer(uint64_t key) const { const auto it = buffers.find(key); if (it == buffers.end()) { AUDIO_DEBUG_PRINT("Buffer not found"); From 56ee049a573daca2b55e50130a2c64b72168d57c Mon Sep 17 00:00:00 2001 From: Samuel Gomes Date: Tue, 27 Aug 2024 00:11:59 +0530 Subject: [PATCH 2/3] Replace usage of raw pointers with std::vector --- internal/c/parts/audio/framework.h | 110 ++++++++++++++--------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/internal/c/parts/audio/framework.h b/internal/c/parts/audio/framework.h index 10f370c16..3be905474 100644 --- a/internal/c/parts/audio/framework.h +++ b/internal/c/parts/audio/framework.h @@ -60,14 +60,15 @@ extern InstrumentBankManager g_InstrumentBankManager; void AudioEngineAttachCustomBackendVTables(ma_resource_manager_config *maResourceManagerConfig); void AudioEngineAttachCustomBackendVTables(ma_decoder_config *maDecoderConfig); -/// @brief A class that can manage a list of buffers using unique keys +/// @brief A class that can manage a list of buffers using unique keys. class BufferMap { private: - /// @brief A buffer that is made up of a raw pointer, size and reference count + /// @brief A buffer that is made up of std::vector of bytes and reference count. struct Buffer { - void *data; - size_t size; + std::vector data; size_t refCount; + + Buffer(const void *src, size_t size) : data(size), refCount(1) { std::memcpy(data.data(), src, size); } }; std::unordered_map buffers; @@ -77,84 +78,83 @@ class BufferMap { BufferMap &operator=(const BufferMap &) = delete; BufferMap &operator=(BufferMap &&) = delete; - /// @brief This will simply free all buffers that were allocated - ~BufferMap() { - for (auto &it : buffers) { - free(it.second.data); - AUDIO_DEBUG_PRINT("Buffer freed of size %llu", it.second.size); - } - } - - /// @brief Adds a buffer to the map using a unique key only if it was not added before - /// @param data The raw data pointer. The data is copied - /// @param size The size of the data - /// @param key The unique key that should be used - /// @return True if successful + /// @brief Adds a buffer to the map using a unique key only if it was not added before. If the buffer is already present then it increases the reference + /// count. + /// @param data The raw data pointer. The data is copied. + /// @param size The size of the data. + /// @param key The unique key that should be used. + /// @return True if successful. bool AddBuffer(const void *data, size_t size, uint64_t key) { - if (data && size && key && buffers.find(key) == buffers.end()) { - Buffer buf = {}; + if (data && size) { + auto it = buffers.find(key); + + if (it == buffers.end()) { + buffers.emplace(std::make_pair(key, Buffer(data, size))); - buf.data = malloc(size); - if (!buf.data) - return false; + AUDIO_DEBUG_PRINT("Added buffer of size %llu to map", size); + } else { + it->second.refCount++; - buf.size = size; - buf.refCount = 1; - memcpy(buf.data, data, size); - buffers.emplace(key, std::move(buf)); + AUDIO_DEBUG_PRINT("Increased reference count to %llu", it->second.refCount); + } - AUDIO_DEBUG_PRINT("Added buffer of size %llu to map", size); return true; } - AUDIO_DEBUG_PRINT("Failed to add buffer of size %llu", size); + AUDIO_DEBUG_PRINT("Invalid buffer or size %p, %llu", data, size); + return false; } - /// @brief Increments the buffer reference count - /// @param key The unique key for the buffer + /// @brief Increments the buffer reference count. + /// @param key The unique key for the buffer. void AddRef(uint64_t key) { - const auto it = buffers.find(key); + auto it = buffers.find(key); + if (it != buffers.end()) { - auto &buf = it->second; - buf.refCount += 1; - AUDIO_DEBUG_PRINT("Increased reference count to %llu", buf.refCount); + it->second.refCount++; + + AUDIO_DEBUG_PRINT("Increased reference count to %llu", it->second.refCount); } else { AUDIO_DEBUG_PRINT("Buffer not found"); } } - /// @brief Decrements the buffer reference count and frees the buffer if the reference count reaches zero - /// @param key The unique key for the buffer + /// @brief Decrements the buffer reference count and frees the buffer if the reference count reaches zero. + /// @param key The unique key for the buffer. void Release(uint64_t key) { - const auto it = buffers.find(key); + auto it = buffers.find(key); + if (it != buffers.end()) { - auto &buf = it->second; - buf.refCount -= 1; - AUDIO_DEBUG_PRINT("Decreased reference count to %llu", buf.refCount); - - if (buf.refCount < 1) { - free(buf.data); - AUDIO_DEBUG_PRINT("Buffer freed of size %llu", buf.size); - buffers.erase(key); + it->second.refCount--; + + AUDIO_DEBUG_PRINT("Decreased reference count to %llu", it->second.refCount); + + if (it->second.refCount == 0) { + AUDIO_DEBUG_PRINT("Erasing buffer of size %llu", it->second.data.size()); + + buffers.erase(it); } } else { AUDIO_DEBUG_PRINT("Buffer not found"); } } - /// @brief Gets the raw pointer and size of the buffer with the given key - /// @param key The unique key for the buffer - /// @return An std::pair of the buffer raw pointer and size + /// @brief Gets the raw pointer and size of the buffer with the given key. + /// @param key The unique key for the buffer. + /// @return An std::pair of the buffer raw pointer and size. std::pair GetBuffer(uint64_t key) const { - const auto it = buffers.find(key); - if (it == buffers.end()) { - AUDIO_DEBUG_PRINT("Buffer not found"); - return {nullptr, 0}; + auto it = buffers.find(key); + + if (it != buffers.end()) { + AUDIO_DEBUG_PRINT("Returning buffer of size %llu", it->second.data.size()); + + return {it->second.data.data(), it->second.data.size()}; } - const auto &buf = it->second; - AUDIO_DEBUG_PRINT("Returning buffer of size %llu", buf.size); - return {buf.data, buf.size}; + + AUDIO_DEBUG_PRINT("Buffer not found"); + + return {nullptr, 0}; } }; From ccc4b9c653281d05f958c4443ff5e9c51a9a89e4 Mon Sep 17 00:00:00 2001 From: Samuel Gomes Date: Tue, 27 Aug 2024 00:17:59 +0530 Subject: [PATCH 3/3] Bump version to 3.14.1 --- source/global/version.bas | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/global/version.bas b/source/global/version.bas index 078324ab6..0abad9df9 100644 --- a/source/global/version.bas +++ b/source/global/version.bas @@ -1,9 +1,9 @@ DIM SHARED Version AS STRING DIM SHARED IsCiVersion AS _BYTE -Version$ = "3.14.0" -$VERSIONINFO:FILEVERSION#=3,14,0,0 -$VERSIONINFO:PRODUCTVERSION#=3,14,0,0 +Version$ = "3.14.1" +$VERSIONINFO:FILEVERSION#=3,14,1,0 +$VERSIONINFO:PRODUCTVERSION#=3,14,1,0 ' If ./internal/version.txt exist, then this is some kind of CI build with a label IF _FILEEXISTS("internal/version.txt") THEN