From 8b3506186e5c9c810bcbe4a4206874d9fd4dfe9b Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Fri, 14 Apr 2017 20:39:32 +0200 Subject: Add chunk size control to the audio cache engine. --- src/audiocache.cc | 29 +++++++++++++++++++++-------- src/audiocache.h | 10 +++++++--- src/drumgizmo.cc | 2 +- src/drumkitloader.cc | 6 +++++- src/drumkitloader.h | 4 +++- 5 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/audiocache.cc b/src/audiocache.cc index 7d80ae9..aecb208 100644 --- a/src/audiocache.cc +++ b/src/audiocache.cc @@ -35,8 +35,6 @@ #include "audiocachefile.h" -#define CHUNKSIZE(x) (x * CHUNK_MULTIPLIER) - AudioCache::AudioCache(Settings& settings) : settings(settings) { @@ -137,7 +135,7 @@ sample_t* AudioCache::open(const AudioFile& file, if(c.back == nullptr) { - c.back = new sample_t[CHUNKSIZE(framesize)]; + c.back = new sample_t[chunk_size]; } event_handler.pushLoadNextEvent(c.afile, c.channel, c.pos, @@ -184,7 +182,7 @@ sample_t* AudioCache::next(cacheid_t id, std::size_t& size) { // We are playing from cache: - if(c.localpos < CHUNKSIZE(framesize)) + if(c.localpos < chunk_size) { sample_t* s = c.front + c.localpos; c.localpos += framesize; @@ -206,7 +204,7 @@ sample_t* AudioCache::next(cacheid_t id, std::size_t& size) // Next time we go here we have already read the first frame. c.localpos = framesize; - c.pos += CHUNKSIZE(framesize); + c.pos += chunk_size; // Does the file have remaining unread samples? assert(c.afile); // Assert that we have an audio file. @@ -215,7 +213,7 @@ sample_t* AudioCache::next(cacheid_t id, std::size_t& size) // Do we have a back buffer to read into? if(c.back == nullptr) { - c.back = new sample_t[CHUNKSIZE(framesize)]; + c.back = new sample_t[chunk_size]; } event_handler.pushLoadNextEvent(c.afile, c.channel, c.pos, @@ -273,8 +271,6 @@ void AudioCache::setFrameSize(std::size_t framesize) } this->framesize = framesize; - - event_handler.setChunkSize(CHUNKSIZE(framesize)); } std::size_t AudioCache::getFrameSize() const @@ -282,6 +278,23 @@ std::size_t AudioCache::getFrameSize() const return framesize; } +void AudioCache::updateChunkSize(std::size_t output_channels) +{ + // Make sure we won't get out-of-range chunk sizes. + std::size_t disk_cache_chunk_size = + std::max(settings.disk_cache_chunk_size.load(), std::size_t(512u * 1024u)); + output_channels = std::max(output_channels, std::size_t(1u)); + + // 1MB pr. chunk divided over 16 channels, 4 bytes pr. sample. + const auto ideal_chunk_size = + disk_cache_chunk_size / output_channels / sizeof(sample_t); + + // Chunk size must match a whole number of frames. + chunk_size = (ideal_chunk_size / framesize) * framesize; + + event_handler.setChunkSize(chunk_size); +} + void AudioCache::setAsyncMode(bool async) { event_handler.setThreaded(async); diff --git a/src/audiocache.h b/src/audiocache.h index 475f1aa..54abcf7 100644 --- a/src/audiocache.h +++ b/src/audiocache.h @@ -38,9 +38,8 @@ #include "audiocacheeventhandler.h" #include "settings.h" -#define CHUNK_MULTIPLIER 16 - -class AudioCache { +class AudioCache +{ public: AudioCache(Settings& settings); @@ -92,6 +91,10 @@ public: void setFrameSize(std::size_t framesize); std::size_t getFrameSize() const; + //! Signal the AudioCache sub-system to set it's internals according to the + //! chunk size parameter from Settings. + void updateChunkSize(std::size_t output_channels); + //! Control/get reader threaded mode. //! True means reading happening threaded, false means all reading done //! synchronious. @@ -102,6 +105,7 @@ private: std::size_t framesize{0}; sample_t* nodata{nullptr}; std::size_t nodata_framesize{0}; + std::size_t chunk_size{0}; AudioCacheIDManager id_manager; AudioCacheEventHandler event_handler{id_manager}; diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc index 2b4007d..592fa20 100644 --- a/src/drumgizmo.cc +++ b/src/drumgizmo.cc @@ -42,7 +42,7 @@ DrumGizmo::DrumGizmo(Settings& settings, AudioOutputEngine& o, AudioInputEngine& i) - : loader(settings, kit, i, resamplers, rand) + : loader(settings, kit, i, resamplers, rand, audio_cache) , oe(o) , ie(i) , audio_cache(settings) diff --git a/src/drumkitloader.cc b/src/drumkitloader.cc index 8ec47a5..e4d34f2 100644 --- a/src/drumkitloader.cc +++ b/src/drumkitloader.cc @@ -37,13 +37,15 @@ DrumKitLoader::DrumKitLoader(Settings& settings, DrumKit& kit, AudioInputEngine& ie, Resamplers& resamplers, - Random& rand) + Random& rand, + AudioCache& audio_cache) : settings(settings) , getter(settings) , kit(kit) , ie(ie) , resamplers(resamplers) , rand(rand) + , audio_cache(audio_cache) { } @@ -193,6 +195,8 @@ void DrumKitLoader::loadKit(DrumKit *kit) DEBUG(loader, "Queued %d (size: %d) AudioFiles for loading.\n", (int)settings.number_of_files.load(), (int)load_queue.size()); + audio_cache.updateChunkSize(kit->channels.size()); + semaphore.post(); // Start loader loop. } diff --git a/src/drumkitloader.h b/src/drumkitloader.h index c36194c..22fa310 100644 --- a/src/drumkitloader.h +++ b/src/drumkitloader.h @@ -39,6 +39,7 @@ #include "audioinputengine.h" #include "chresampler.h" #include "memchecker.h" +#include "audiocache.h" //! This class is responsible for loading the drumkits in its own thread. //! All interaction calls are simply modifying queues and not doing any @@ -50,7 +51,7 @@ class DrumKitLoader { public: DrumKitLoader(Settings& settings, DrumKit& kit, AudioInputEngine& ie, - Resamplers& resamplers, Random& rand); + Resamplers& resamplers, Random& rand, AudioCache& audio_cache); ~DrumKitLoader(); @@ -92,5 +93,6 @@ protected: Resamplers& resamplers; MemChecker memchecker; Random& rand; + AudioCache& audio_cache; std::size_t preload_samples{std::numeric_limits::max()}; }; -- cgit v1.2.3