From 6c5b062ba00388951b67dc1ea555dc6ad8af4ede Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Wed, 22 Mar 2017 20:19:45 +0100 Subject: Use cache limit for preloading. Add re-load support through reload counter. Refactor AudioFile. --- src/audiofile.cc | 68 +++++++++++++++++++++++++++---------------------- src/audiofile.h | 22 ++++++++-------- src/drumkitloader.cc | 50 ++++++++++++++++++++++++++++-------- src/drumkitloader.h | 3 ++- src/instrumentparser.cc | 2 +- 5 files changed, 91 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/src/audiofile.cc b/src/audiofile.cc index 84329f8..a929a32 100644 --- a/src/audiofile.cc +++ b/src/audiofile.cc @@ -28,24 +28,23 @@ */ #include "audiofile.h" -#include +#include #include #include #include + #include -#include -AudioFile::AudioFile(const std::string& filename, int filechannel) -{ - is_loaded = false; - this->filename = filename; - this->filechannel = filechannel; +#include - data = nullptr; - size = 0; +#include - magic = this; +AudioFile::AudioFile(const std::string& filename, std::size_t filechannel) + : filename(filename) + , filechannel(filechannel) + , magic{this} +{ } AudioFile::~AudioFile() @@ -56,6 +55,7 @@ AudioFile::~AudioFile() bool AudioFile::isValid() const { + assert(this == magic); return this == magic; } @@ -66,19 +66,20 @@ void AudioFile::unload() is_loaded = false; + preloadedsize = 0; + size = 0; delete[] data; data = nullptr; - size = 0; } -#define BUFFER_SIZE 4092 +#define BUFFER_SIZE 4096 -void AudioFile::load(int num_samples) +void AudioFile::load(std::size_t sample_limit) { // Make sure we don't unload the object while loading it... MutexAutolock l(mutex); - if(data) + if(this->data) // already loaded { return; } @@ -92,17 +93,18 @@ void AudioFile::load(int num_samples) return; } - if(num_samples == ALL_SAMPLES) + if(sf_info.channels < 1) { - num_samples = sf_info.frames; + // This should never happen but lets check just in case. + return; } - size = sf_info.frames; - preloadedsize = sf_info.frames; + std::size_t size = sf_info.frames; + std::size_t preloadedsize = sf_info.frames; - if(preloadedsize > (size_t)num_samples) + if(preloadedsize > sample_limit) { - preloadedsize = num_samples; + preloadedsize = sample_limit; } sample_t* data = new sample_t[preloadedsize]; @@ -113,35 +115,39 @@ void AudioFile::load(int num_samples) else { // check filechannel exists - if(filechannel >= sf_info.channels) + if(filechannel >= (std::size_t)sf_info.channels) { filechannel = sf_info.channels - 1; } sample_t buffer[BUFFER_SIZE]; - int readsize = BUFFER_SIZE / sf_info.channels; - int totalread = 0; - int read; + std::size_t frame_count = BUFFER_SIZE / sf_info.channels; + std::size_t total_frames_read = 0; + int frames_read; do { - read = sf_readf_float(fh, buffer, readsize); - for(int i = 0; (i < read) && (totalread < num_samples); ++i) + frames_read = sf_readf_float(fh, buffer, frame_count); + for(int i = 0; + (i < frames_read) && (total_frames_read < sample_limit); + ++i) { - data[totalread++] = buffer[i * sf_info.channels + filechannel]; + data[total_frames_read++] = buffer[i * sf_info.channels + filechannel]; } } - while( (read > 0) && - (totalread < (int)preloadedsize) && - (totalread < num_samples) ); + while( (frames_read > 0) && + (total_frames_read < preloadedsize) && + (total_frames_read < sample_limit) ); // set data size to total bytes read - preloadedsize = totalread; + preloadedsize = total_frames_read; } sf_close(fh); this->data = data; + this->size = size; + this->preloadedsize = preloadedsize; is_loaded = true; } diff --git a/src/audiofile.h b/src/audiofile.h index c310a55..07b40dd 100644 --- a/src/audiofile.h +++ b/src/audiofile.h @@ -29,27 +29,27 @@ #include #include #include +#include #include #include "mutex.h" #include "audio.h" -#define ALL_SAMPLES -1 - -class AudioFile { +class AudioFile +{ public: - AudioFile(const std::string& filename, int filechannel); + AudioFile(const std::string& filename, std::size_t filechannel); ~AudioFile(); - void load(int num_samples = ALL_SAMPLES); + void load(std::size_t sample_limit = std::numeric_limits::max()); void unload(); bool isLoaded() const; - volatile size_t size{0}; // Full size of the file - volatile size_t preloadedsize{0}; // Number of samples preloaded (in data) - sample_t *data{nullptr}; + volatile std::size_t size{0}; // Full size of the file + volatile std::size_t preloadedsize{0}; // Number of samples preloaded (in data) + sample_t* data{nullptr}; std::string filename; @@ -57,9 +57,9 @@ public: Mutex mutex; - int filechannel; + std::size_t filechannel; private: - void *magic; - volatile bool is_loaded; + void* magic{nullptr}; + volatile bool is_loaded{false}; }; diff --git a/src/drumkitloader.cc b/src/drumkitloader.cc index 103b60c..8ec47a5 100644 --- a/src/drumkitloader.cc +++ b/src/drumkitloader.cc @@ -141,6 +141,37 @@ void DrumKitLoader::loadKit(DrumKit *kit) DEBUG(loader, "Create AudioFile queue from DrumKit\n"); + auto cache_limit = settings.disk_cache_upper_limit.load(); + auto cache_enable = settings.disk_cache_enable.load(); + + DEBUG(loader, "cache_enable: %s\n", cache_enable?"true":"false"); + + if(cache_enable) + { + auto number_of_files = kit->getNumberOfFiles(); + auto cache_limit_per_file = cache_limit / number_of_files; + + assert(framesize != 0); + + preload_samples = cache_limit_per_file / sizeof(sample_t); + + if(preload_samples < 4096) + { + preload_samples = 4096; + } + + DEBUG(loader, "cache_limit: %lu, number_of_files: %lu," + " cache_limit_per_file: %lu, preload_samples: %lu\n", + (unsigned long)cache_limit, + (unsigned long)number_of_files, + (unsigned long)cache_limit_per_file, + (unsigned long)preload_samples); + } + else + { + preload_samples = std::numeric_limits::max(); + } + settings.number_of_files_loaded.store(0); // Count total number of files that need loading: @@ -171,7 +202,7 @@ void DrumKitLoader::skip() load_queue.clear(); } -void DrumKitLoader::setFrameSize(size_t framesize) +void DrumKitLoader::setFrameSize(std::size_t framesize) { std::lock_guard guard(mutex); this->framesize = framesize; @@ -188,7 +219,7 @@ void DrumKitLoader::thread_main() while(running) { - size_t size; + std::size_t size; { std::lock_guard guard(mutex); size = load_queue.size(); @@ -240,16 +271,15 @@ void DrumKitLoader::thread_main() AudioFile *audiofile = load_queue.front(); load_queue.pop_front(); filename = audiofile->filename; - int preload_size = framesize * CHUNK_MULTIPLIER + framesize; - if(preload_size < 1024) + try { - preload_size = 1024; + audiofile->load(preload_samples); + } + catch(std::bad_alloc&) + { + settings.drumkit_load_status.store(LoadStatus::Error); + load_queue.clear(); } - - // Note: Remove this line to enable diskstreaming - preload_size = ALL_SAMPLES; - - audiofile->load(preload_size); } settings.number_of_files_loaded.fetch_add(1); diff --git a/src/drumkitloader.h b/src/drumkitloader.h index 9608e14..c36194c 100644 --- a/src/drumkitloader.h +++ b/src/drumkitloader.h @@ -73,7 +73,7 @@ public: //! Set the framesize which will be used to preloading samples in next //! loadKit call. - void setFrameSize(size_t framesize); + void setFrameSize(std::size_t framesize); protected: void thread_main(); @@ -92,4 +92,5 @@ protected: Resamplers& resamplers; MemChecker memchecker; Random& rand; + std::size_t preload_samples{std::numeric_limits::max()}; }; diff --git a/src/instrumentparser.cc b/src/instrumentparser.cc index af876a8..45e76d8 100644 --- a/src/instrumentparser.cc +++ b/src/instrumentparser.cc @@ -129,7 +129,7 @@ void InstrumentParser::startTag(const std::string& name, const attr_t& attr) return; } - int filechannel = 1; // default, override with optional attribute + std::size_t filechannel = 1; // default, override with optional attribute if(attr.find("filechannel") != attr.end()) { filechannel = std::stoi(attr.at("filechannel")); -- cgit v1.2.3