diff options
| -rw-r--r-- | src/audiofile.cc | 68 | ||||
| -rw-r--r-- | src/audiofile.h | 22 | ||||
| -rw-r--r-- | src/drumkitloader.cc | 50 | ||||
| -rw-r--r-- | src/drumkitloader.h | 3 | ||||
| -rw-r--r-- | src/instrumentparser.cc | 2 | ||||
| -rw-r--r-- | test/audiocachetest.cc | 2 | 
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); | 
