summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2017-03-22 20:19:45 +0100
committerBent Bisballe Nyeng <deva@aasimon.org>2017-03-23 20:17:53 +0100
commit6c5b062ba00388951b67dc1ea555dc6ad8af4ede (patch)
tree2ebc3884a6423d39c6729bd7e1e018e1f504d49a
parenta6c134a82143acd32f80b2f9679f8fcf194a5402 (diff)
Use cache limit for preloading. Add re-load support through reload counter. Refactor AudioFile.
-rw-r--r--src/audiofile.cc68
-rw-r--r--src/audiofile.h22
-rw-r--r--src/drumkitloader.cc50
-rw-r--r--src/drumkitloader.h3
-rw-r--r--src/instrumentparser.cc2
-rw-r--r--test/audiocachetest.cc2
6 files changed, 92 insertions, 55 deletions
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 <config.h>
+#include <cassert>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
+
#include <sndfile.h>
-#include <hugin.hpp>
-AudioFile::AudioFile(const std::string& filename, int filechannel)
-{
- is_loaded = false;
- this->filename = filename;
- this->filechannel = filechannel;
+#include <config.h>
- data = nullptr;
- size = 0;
+#include <hugin.hpp>
- 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 <string>
#include <map>
#include <vector>
+#include <limits>
#include <sndfile.h>
#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<std::size_t>::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<std::size_t>::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<std::mutex> 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<std::mutex> 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<std::size_t>::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"));
diff --git a/test/audiocachetest.cc b/test/audiocachetest.cc
index 546a5c4..b194b14 100644
--- a/test/audiocachetest.cc
+++ b/test/audiocachetest.cc
@@ -61,7 +61,7 @@ public:
// Reference file:
AudioFile audio_file_ref(filename, channel);
printf("audio_file_ref.load\n");
- audio_file_ref.load(ALL_SAMPLES);
+ audio_file_ref.load();
// Input file:
AudioFile audio_file(filename, channel);