diff options
| -rw-r--r-- | src/audiocache.cc | 14 | ||||
| -rw-r--r-- | src/audiocacheeventhandler.cc | 44 | ||||
| -rw-r--r-- | src/audiocacheeventhandler.h | 8 | ||||
| -rw-r--r-- | src/audiocacheidmanager.cc | 53 | ||||
| -rw-r--r-- | src/audiocacheidmanager.h | 39 | ||||
| -rw-r--r-- | test/audiocacheidmanagertest.cc | 14 | 
6 files changed, 97 insertions, 75 deletions
| diff --git a/src/audiocache.cc b/src/audiocache.cc index fa144fd..92d3d61 100644 --- a/src/audiocache.cc +++ b/src/audiocache.cc @@ -91,8 +91,8 @@ gsl::owner<sample_t*> AudioCache::open(const AudioFile& file,  		return nodata;  	} -	// Get the cache_t connected with the registered id. -	cache_t& cache = id_manager.getCache(new_cacheid); +	// Get the CacheBuffer connected with the registered id. +	CacheBuffer& cache = id_manager.getCache(new_cacheid);  	cache.afile = nullptr; // File is opened when needed.  	cache.channel = channel; @@ -140,7 +140,7 @@ gsl::owner<sample_t*> AudioCache::open(const AudioFile& file,  		if(cache.back == nullptr)  		{ -			cache.back = new sample_t[chunk_size]; +			cache.allocBack(chunk_size);  		}  		event_handler.pushLoadNextEvent(cache.afile, cache.channel, cache.pos, @@ -159,7 +159,7 @@ gsl::owner<sample_t*> AudioCache::next(cacheid_t cacheid, std::size_t& size)  		return nodata;  	} -	cache_t& cache = id_manager.getCache(cacheid); +	CacheBuffer& cache = id_manager.getCache(cacheid);  	if(cache.preloaded_samples != nullptr)  	{ @@ -210,7 +210,7 @@ gsl::owner<sample_t*> AudioCache::next(cacheid_t cacheid, std::size_t& size)  	}  	// Swap buffers -	std::swap(cache.front, cache.back); +	cache.swap();  	// Next time we go here we have already read the first frame.  	cache.localpos = size; @@ -224,7 +224,7 @@ gsl::owner<sample_t*> AudioCache::next(cacheid_t cacheid, std::size_t& size)  		// Do we have a back buffer to read into?  		if(cache.back == nullptr)  		{ -			cache.back = new sample_t[chunk_size]; +			cache.allocBack(chunk_size);  		}  		event_handler.pushLoadNextEvent(cache.afile, cache.channel, cache.pos, @@ -243,7 +243,7 @@ bool AudioCache::isReady(cacheid_t cacheid)  		return true;  	} -	const cache_t& cache = id_manager.getCache(cacheid); +	const CacheBuffer& cache = id_manager.getCache(cacheid);  	return cache.ready;  } diff --git a/src/audiocacheeventhandler.cc b/src/audiocacheeventhandler.cc index 06bbf6e..ffd183c 100644 --- a/src/audiocacheeventhandler.cc +++ b/src/audiocacheeventhandler.cc @@ -34,13 +34,14 @@  #include "audiocache.h"  #include "audiocacheidmanager.h" -enum class EventType { +enum class EventType +{  	LoadNext,  	Close,  }; -class CacheEvent { -public: +struct CacheEvent +{  	EventType event_type;  	// For close event: @@ -63,9 +64,9 @@ AudioCacheEventHandler::~AudioCacheEventHandler()  	clearEvents();  	auto active_ids = id_manager.getActiveIDs(); -	for(auto id : active_ids) +	for(auto active_id : active_ids)  	{ -		handleCloseCache(id); +		handleCloseCache(active_id);  	}  } @@ -119,28 +120,28 @@ void AudioCacheEventHandler::pushLoadNextEvent(AudioCacheFile* afile,                                                 size_t pos, sample_t* buffer,                                                 volatile bool* ready)  { -	CacheEvent cache_event; +	CacheEvent cache_event{};  	cache_event.event_type = EventType::LoadNext;  	cache_event.pos = pos;  	cache_event.afile = afile; -	CacheChannel c{}; -	c.channel_index = channel_index; -	c.samples = buffer; +	CacheChannel cache_channel{}; +	cache_channel.channel_index = channel_index; +	cache_channel.samples = buffer;  	*ready = false; -	c.ready = ready; +	cache_channel.ready = ready; -	cache_event.channels.insert(cache_event.channels.end(), c); +	cache_event.channels.insert(cache_event.channels.end(), cache_channel);  	pushEvent(cache_event);  } -void AudioCacheEventHandler::pushCloseEvent(cacheid_t id) +void AudioCacheEventHandler::pushCloseEvent(cacheid_t cacheid)  { -	CacheEvent cache_event; +	CacheEvent cache_event{};  	cache_event.event_type = EventType::Close; -	cache_event.id = id; +	cache_event.id = cacheid;  	pushEvent(cache_event);  } @@ -197,7 +198,7 @@ void AudioCacheEventHandler::clearEvents()  	eventqueue.clear();  } -void AudioCacheEventHandler::handleLoadNextEvent(CacheEvent& cache_event) +void AudioCacheEventHandler::handleLoadNextEvent(CacheEvent& cache_event) const  {  	assert(cache_event.afile); // Assert that we have an audio file @@ -211,20 +212,21 @@ void AudioCacheEventHandler::handleCloseEvent(CacheEvent& cache_event)  	handleCloseCache(cache_event.id);  } -void AudioCacheEventHandler::handleCloseCache(cacheid_t id) +void AudioCacheEventHandler::handleCloseCache(cacheid_t cacheid)  { -	auto& cache = id_manager.getCache(id); +	auto& cache = id_manager.getCache(cacheid);  	// Only close the file if we have also opened it. -	if(cache.afile) +	if(cache.afile != nullptr)  	{  		files.releaseFile(cache.afile->getFilename());  	} -	delete[] cache.front; -	delete[] cache.back; +	//delete[] cache.front; +	//delete[] cache.back; +	cache.deleteChunks(); -	id_manager.releaseID(id); +	id_manager.releaseID(cacheid);  }  void AudioCacheEventHandler::handleEvent(CacheEvent& cache_event) diff --git a/src/audiocacheeventhandler.h b/src/audiocacheeventhandler.h index 8de812b..e676f6e 100644 --- a/src/audiocacheeventhandler.h +++ b/src/audiocacheeventhandler.h @@ -36,7 +36,7 @@  #include "audiocachefile.h"  #include "audiocacheidmanager.h" -class CacheEvent; +struct CacheEvent;  class AudioCacheEventHandler  	: protected Thread @@ -71,7 +71,7 @@ public:  	void pushLoadNextEvent(AudioCacheFile* afile, size_t channel_index,  	                       size_t pos, sample_t* buffer,  	                       volatile bool* ready); -	void pushCloseEvent(cacheid_t id); +	void pushCloseEvent(cacheid_t cacheid);  	void setChunkSize(size_t chunksize);  	size_t getChunkSize() const; @@ -81,13 +81,13 @@ public:  protected:  	void clearEvents(); -	void handleLoadNextEvent(CacheEvent& cache_event); +	void handleLoadNextEvent(CacheEvent& cache_event) const;  	//! Lock the mutex and calls handleCloseCache  	void handleCloseEvent(CacheEvent& cache_event);  	//! Close decrease the file ref and release the cache id. -	void handleCloseCache(cacheid_t id); +	void handleCloseCache(cacheid_t cacheid);  	void handleEvent(CacheEvent& cache_event); diff --git a/src/audiocacheidmanager.cc b/src/audiocacheidmanager.cc index 693ed3c..80b0f98 100644 --- a/src/audiocacheidmanager.cc +++ b/src/audiocacheidmanager.cc @@ -29,6 +29,21 @@  #include <limits>  #include <cassert> +void CacheBuffer::allocBack(std::size_t chunk_size) +{ +	back = new sample_t[chunk_size]; +} + +void CacheBuffer::deleteChunks() const +{ +	delete[] front; +	delete[] back; +} + +void CacheBuffer::swap() noexcept +{ +	std::swap(front, back); +}  AudioCacheIDManager::~AudioCacheIDManager()  { @@ -41,30 +56,30 @@ void AudioCacheIDManager::init(unsigned int capacity)  	id2cache.resize(capacity);  	available_ids.resize(capacity); -	for(size_t i = 0; i < capacity; ++i) +	for(int i = 0; i < static_cast<int>(capacity); ++i)  	{  		available_ids[i] = i;  	}  } -cache_t& AudioCacheIDManager::getCache(cacheid_t id) +CacheBuffer& AudioCacheIDManager::getCache(cacheid_t cacheid)  {  	const std::lock_guard<std::mutex> guard(mutex); -	assert(id != CACHE_NOID); -	assert(id != CACHE_DUMMYID); -	assert(id >= 0); -	assert(id < (int)id2cache.size()); -	assert(id2cache[id].id == id); +	assert(cacheid != CACHE_NOID); +	assert(cacheid != CACHE_DUMMYID); +	assert(cacheid >= 0); +	assert(cacheid < (int)id2cache.size()); +	assert(id2cache[cacheid].id == cacheid); -	return id2cache[id]; +	return id2cache[cacheid];  } -cacheid_t AudioCacheIDManager::registerID(const cache_t& cache) +cacheid_t AudioCacheIDManager::registerID(const CacheBuffer& cache)  {  	const std::lock_guard<std::mutex> guard(mutex); -	cacheid_t id = CACHE_NOID; +	cacheid_t cacheid = CACHE_NOID;  	if(available_ids.empty())  	{ @@ -72,27 +87,27 @@ cacheid_t AudioCacheIDManager::registerID(const cache_t& cache)  	}  	else  	{ -		id = available_ids.back(); +		cacheid = available_ids.back();  		available_ids.pop_back();  	} -	assert(id2cache[id].id == CACHE_NOID); // Make sure it is not already in use +	assert(id2cache[cacheid].id == CACHE_NOID); // Make sure it is not already in use -	id2cache[id] = cache; -	id2cache[id].id = id; +	id2cache[cacheid] = cache; +	id2cache[cacheid].id = cacheid; -	return id; +	return cacheid;  } -void AudioCacheIDManager::releaseID(cacheid_t id) +void AudioCacheIDManager::releaseID(cacheid_t cacheid)  {  	const std::lock_guard<std::mutex> guard(mutex); -	assert(id2cache[id].id != CACHE_NOID); // Test if it wasn't already released. +	assert(id2cache[cacheid].id != CACHE_NOID); // Test if it wasn't already released. -	id2cache[id].id = CACHE_NOID; +	id2cache[cacheid].id = CACHE_NOID; -	available_ids.push_back(id); +	available_ids.push_back(cacheid);  }  void AudioCacheIDManager::disableActive() diff --git a/src/audiocacheidmanager.h b/src/audiocacheidmanager.h index 2bbe09d..d440415 100644 --- a/src/audiocacheidmanager.h +++ b/src/audiocacheidmanager.h @@ -36,25 +36,30 @@  class AudioCacheFile; -#define CACHE_DUMMYID -2 -#define CACHE_NOID -1 +using cacheid_t = int; -typedef int cacheid_t; +constexpr cacheid_t CACHE_DUMMYID{-2}; +constexpr cacheid_t CACHE_NOID{-1}; -struct cache_t +class CacheBuffer  { -	cacheid_t id{CACHE_NOID}; //< Current id of this cache_t. CACHE_NOID means not in use. +public: +	void allocBack(std::size_t chunk_size); +	void deleteChunks() const; +	void swap() noexcept; + +	cacheid_t id{CACHE_NOID}; //< Current id of this CacheBuffer. CACHE_NOID means not in use. -	AudioCacheFile* afile{nullptr}; -	size_t channel{0}; -	size_t pos{0}; //< File position +	AudioCacheFile* afile{}; +	size_t channel{}; +	size_t pos{}; //< File position  	volatile bool ready{false}; -	gsl::owner<sample_t*> front{nullptr}; -	gsl::owner<sample_t*> back{nullptr}; -	size_t localpos{0}; //< Intra buffer (front) position. +	gsl::owner<sample_t*> front{}; +	gsl::owner<sample_t*> back{}; +	size_t localpos{}; //< Intra buffer (front) position. -	sample_t* preloaded_samples{nullptr}; // nullptr means preload buffer not active. -	size_t preloaded_samples_size{0}; +	sample_t* preloaded_samples{}; // nullptr means preload buffer not active. +	size_t preloaded_samples_size{};  };  class AudioCacheIDManager @@ -71,16 +76,16 @@ public:  	//! Get the cache object connected with the specified cacheid.  	//! Note: The cacheid MUST be active. -	cache_t& getCache(cacheid_t id); +	CacheBuffer& getCache(cacheid_t cacheid);  	//! Reserve a new cache object and return its cacheid.  	//! The contents of the supplied cache object will be copied to the new  	//! cache object. -	cacheid_t registerID(const cache_t& cache); +	cacheid_t registerID(const CacheBuffer& cache);  	//! Release a cache object and its correseponding cacheid.  	//! After this call the cacheid can no longer be used. -	void releaseID(cacheid_t id); +	void releaseID(cacheid_t cacheid);  protected:  	// For AudioCacheEventHandler @@ -89,6 +94,6 @@ protected:  	std::mutex mutex; -	std::vector<cache_t> id2cache; +	std::vector<CacheBuffer> id2cache;  	std::vector<cacheid_t> available_ids;  }; diff --git a/test/audiocacheidmanagertest.cc b/test/audiocacheidmanagertest.cc index c84926b..9d8be25 100644 --- a/test/audiocacheidmanagertest.cc +++ b/test/audiocacheidmanagertest.cc @@ -52,39 +52,39 @@ public:  		TestableAudioCacheIDManager manager;  		manager.init(2); -		cache_t c1; c1.afile = (AudioCacheFile*)1; +		CacheBuffer c1; c1.afile = (AudioCacheFile*)1;  		auto id1 = manager.registerID(c1);  		uUNIT_ASSERT(id1 != CACHE_DUMMYID);  		uUNIT_ASSERT(id1 != CACHE_NOID);  		uUNIT_ASSERT_EQUAL(1, manager.getAvailableIDs()); -		cache_t c2; c2.afile = (AudioCacheFile*)2; +		CacheBuffer c2; c2.afile = (AudioCacheFile*)2;  		auto id2 = manager.registerID(c2);  		uUNIT_ASSERT(id2 != CACHE_DUMMYID);  		uUNIT_ASSERT(id2 != CACHE_NOID);  		uUNIT_ASSERT_EQUAL(0, manager.getAvailableIDs()); -		cache_t c3; c3.afile = (AudioCacheFile*)3; +		CacheBuffer c3; c3.afile = (AudioCacheFile*)3;  		auto id3 = manager.registerID(c3);  		uUNIT_ASSERT(id3 == CACHE_DUMMYID);  		uUNIT_ASSERT_EQUAL(0, manager.getAvailableIDs()); -		cache_t& tc1 = manager.getCache(id1); +		CacheBuffer& tc1 = manager.getCache(id1);  		uUNIT_ASSERT_EQUAL(c1.afile, tc1.afile); -		cache_t& tc2 = manager.getCache(id2); +		CacheBuffer& tc2 = manager.getCache(id2);  		uUNIT_ASSERT_EQUAL(c2.afile, tc2.afile);  		manager.releaseID(id1);  		uUNIT_ASSERT_EQUAL(1, manager.getAvailableIDs()); -		cache_t c4; c4.afile = (AudioCacheFile*)4; +		CacheBuffer c4; c4.afile = (AudioCacheFile*)4;  		auto id4 = manager.registerID(c4);  		uUNIT_ASSERT(id4 != CACHE_DUMMYID);  		uUNIT_ASSERT(id4 != CACHE_NOID);  		uUNIT_ASSERT_EQUAL(0, manager.getAvailableIDs()); -		cache_t& tc4 = manager.getCache(id4); +		CacheBuffer& tc4 = manager.getCache(id4);  		uUNIT_ASSERT_EQUAL(c4.afile, tc4.afile);  		manager.releaseID(id2); | 
