diff --git a/src/sfizz/BufferPool.h b/src/sfizz/BufferPool.h index 8bcb6dcf..752cdfce 100644 --- a/src/sfizz/BufferPool.h +++ b/src/sfizz/BufferPool.h @@ -6,10 +6,15 @@ #pragma once #include "Config.h" +#include "Debug.h" #include "Buffer.h" #include "AudioBuffer.h" #include #include +#ifndef NDEBUG + #include "absl/algorithm/container.h" + #include "MathHelpers.h" +#endif namespace sfz { @@ -23,6 +28,10 @@ public: buffer = std::make_shared>(config::defaultSamplesPerBlock); } + for (auto& buffer : indexBuffers) { + buffer = std::make_shared>(config::defaultSamplesPerBlock); + } + for (auto& buffer : stereoBuffers) { buffer = std::make_shared>(2, config::defaultSamplesPerBlock); } @@ -36,6 +45,12 @@ public: buffer->resize(bufferSize); } + for (auto& buffer: indexBuffers) { + // Trying to resize a buffer in use + ASSERT(buffer.use_count() == 1); + buffer->resize(bufferSize); + } + for (auto& buffer: stereoBuffers) { // Trying to resize a buffer in use ASSERT(buffer.use_count() == 1); @@ -43,7 +58,7 @@ public: } } - std::shared_ptr> getBuffer(size_t numFrames) + std::shared_ptr> getBuffer(size_t numFrames) const { auto bufferIt = buffers.begin(); @@ -57,6 +72,12 @@ public: return {}; } +#ifndef NDEBUG + maxBuffersUsed = max(1 + absl::c_count_if(buffers, [&](const std::shared_ptr>& buffer) { + return (buffer.use_count() > 1); + }), maxBuffersUsed); +#endif + while (bufferIt < buffers.end()) { if (bufferIt->use_count() == 1) return *bufferIt; @@ -68,18 +89,53 @@ public: return {}; } - std::shared_ptr> getStereoBuffer(size_t numFrames) + std::shared_ptr> getIndexBuffer(size_t numFrames) const + { + auto bufferIt = indexBuffers.begin(); + + if (indexBuffers.empty()) { + DBG("[sfizz] No available index buffers in the pool"); + return {}; + } + + if (indexBuffers[0]->size() < numFrames) { + DBG("[sfizz] Someone asked for a index buffer of size " << numFrames << "; only " << indexBuffers[0]->size() << " available..."); + return {}; + } + +#ifndef NDEBUG + maxIndexBuffersUsed = max(1 + absl::c_count_if(indexBuffers, [&](const std::shared_ptr>& buffer) { + return (buffer.use_count() > 1); + }), maxIndexBuffersUsed); +#endif + + while (bufferIt < indexBuffers.end()) { + if (bufferIt->use_count() == 1) + return *bufferIt; + ++bufferIt; + } + + // No buffer found; debug message + DBG("[sfizz] No free index buffer available!"); + return {}; + } + + std::shared_ptr> getStereoBuffer(size_t numFrames) const { if (stereoBuffers.empty()) { - DBG("[sfizz] No available stereoBuffers in the pool"); + DBG("[sfizz] No available stereo buffers in the pool"); return {}; } if (stereoBuffers[0]->getNumFrames() < numFrames) { - DBG("[sfizz] Someone asked for a buffer of size " << numFrames << "; only " << stereoBuffers[0]->getNumFrames() << " available..."); + DBG("[sfizz] Someone asked for a stereo buffer of size " << numFrames << "; only " << stereoBuffers[0]->getNumFrames() << " available..."); return {}; } - +#ifndef NDEBUG + maxStereoBuffersUsed = max(1 + absl::c_count_if(stereoBuffers, [&](const std::shared_ptr>& buffer) { + return (buffer.use_count() > 1); + }), maxStereoBuffersUsed); +#endif auto bufferIt = stereoBuffers.begin(); while (bufferIt < stereoBuffers.end()) { if (bufferIt->use_count() == 1) @@ -88,11 +144,26 @@ public: } // No buffer found; debug message - DBG("[sfizz] No free buffer available!"); + DBG("[sfizz] No free stereo buffer available!"); return {}; } + +#ifndef NDEBUG + ~BufferPool() + { + DBG("Max buffers used: " << maxBuffersUsed); + DBG("Max index buffers used: " << maxIndexBuffersUsed); + DBG("Max stereo buffers used: " << maxStereoBuffersUsed); + } +#endif private: std::array>, config::bufferPoolSize> buffers; + std::array>, config::bufferPoolSize> indexBuffers; std::array>, config::stereoBufferPoolSize> stereoBuffers; +#ifndef NDEBUG + mutable int maxBuffersUsed { 0 }; + mutable int maxIndexBuffersUsed { 0 }; + mutable int maxStereoBuffersUsed { 0 }; +#endif }; } diff --git a/src/sfizz/Config.h b/src/sfizz/Config.h index e4a5aa2a..56bfd12c 100644 --- a/src/sfizz/Config.h +++ b/src/sfizz/Config.h @@ -30,6 +30,7 @@ namespace config { constexpr int maxBlockSize { 8192 }; constexpr int bufferPoolSize { 16 }; constexpr int stereoBufferPoolSize { 4 }; + constexpr int indexBufferPoolSize { 2 }; constexpr int preloadSize { 8192 }; constexpr int loggerQueueSize { 256 }; constexpr int voiceLoggerQueueSize { 256 };