diff options
| author | Bent Bisballe Nyeng <deva@aasimon.org> | 2016-01-29 20:49:18 +0100 | 
|---|---|---|
| committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2016-01-29 20:49:18 +0100 | 
| commit | aa635eb8da9804488513d1f3d422e4810e611bb8 (patch) | |
| tree | 35db06cfe32f360d974503ff8c7562d1ab75f322 /src | |
| parent | 67a23a559e9707f9caf46716df30a8bf71bba9a7 (diff) | |
| parent | 9ebd9aa0c3429f896e6c41f279b570ba36aec674 (diff) | |
Merge branch 'diskstreaming_review_chaot' into diskstreaming
Diffstat (limited to 'src')
| -rw-r--r-- | src/audiocache.cc | 40 | ||||
| -rw-r--r-- | src/audiocache.h | 6 | ||||
| -rw-r--r-- | src/audiocacheeventhandler.cc | 23 | ||||
| -rw-r--r-- | src/audiocacheeventhandler.h | 4 | ||||
| -rw-r--r-- | src/audiocachefile.cc | 35 | ||||
| -rw-r--r-- | src/audiocachefile.h | 7 | ||||
| -rw-r--r-- | src/audiocacheidmanager.cc | 14 | ||||
| -rw-r--r-- | src/audiocacheidmanager.h | 2 | ||||
| -rw-r--r-- | src/audiofile.cc | 4 | ||||
| -rw-r--r-- | src/audiofile.h | 4 | ||||
| -rw-r--r-- | src/drumgizmo.cc | 60 | 
11 files changed, 101 insertions, 98 deletions
| diff --git a/src/audiocache.cc b/src/audiocache.cc index 237a3ff..86052c7 100644 --- a/src/audiocache.cc +++ b/src/audiocache.cc @@ -28,7 +28,6 @@  #include <mutex> -#include <string.h>  #include <stdio.h>  #include <assert.h> @@ -62,10 +61,10 @@ void AudioCache::deinit()  }  // Invariant: initial_samples_needed < preloaded audio data -sample_t* AudioCache::open(AudioFile* file, size_t initial_samples_needed, +sample_t* AudioCache::open(const AudioFile& file, size_t initial_samples_needed,                             int channel, cacheid_t& id)  { -	if(!file->isValid()) +	if(!file.isValid())  	{  		// File preload not yet ready - skip this sample.  		id = CACHE_DUMMYID; @@ -87,7 +86,7 @@ sample_t* AudioCache::open(AudioFile* file, size_t initial_samples_needed,  	// Get the cache_t connected with the registered id.  	cache_t& c = id_manager.getCache(id); -	c.afile = &event_handler.openFile(file->filename); +	c.afile = &event_handler.openFile(file.filename);  	c.channel = channel;  	// Next call to 'next()' will read from this point. @@ -96,26 +95,37 @@ sample_t* AudioCache::open(AudioFile* file, size_t initial_samples_needed,  	c.front = nullptr; // This is allocated when needed.  	c.back = nullptr; // This is allocated when needed. -	// cropped_size is the preload chunk size cropped to sample length. -	size_t cropped_size = file->preloadedsize - c.localpos; -	cropped_size /= framesize; -	cropped_size *= framesize; -	cropped_size += initial_samples_needed; +	size_t cropped_size; -	if(file->preloadedsize == file->size) +	if(file.preloadedsize == file.size)  	{  		// We have preloaded the entire file, so use it. -		cropped_size = file->preloadedsize; +		cropped_size = file.preloadedsize; +	} +	else +	{ +		// Make sure that the preload-data made available to the next() calls +		// fit on frame boundary: +		// +		// [                  all preloaded data                    ] +		// [ initial ][ biggest multiple of full frames ][ the rest ] +		// \                                            / +		//  \----------------------v-------------------/ +		//                     cropped_size +		 +		cropped_size = file.preloadedsize - c.localpos; +		cropped_size -= cropped_size % framesize; +		cropped_size += initial_samples_needed;  	} -	c.preloaded_samples = file->data; +	c.preloaded_samples = file.data;  	c.preloaded_samples_size = cropped_size;  	// Next read from disk will read from this point.  	c.pos = cropped_size;//c.preloaded_samples_size; -	// Only load next buffer if there are more data in the file to be loaded... -	if(c.pos < file->size) +	// Only load next buffer if there is more data in the file to be loaded... +	if(c.pos < file.size)  	{  		if(c.back == nullptr)  		{ @@ -262,7 +272,7 @@ void AudioCache::setAsyncMode(bool async)  bool AudioCache::asyncMode() const  { -	return event_handler.getThreaded(); +	return event_handler.isThreaded();  }  size_t AudioCache::getNumberOfUnderruns() const diff --git a/src/audiocache.h b/src/audiocache.h index 004fcf8..059faa2 100644 --- a/src/audiocache.h +++ b/src/audiocache.h @@ -67,7 +67,7 @@ public:  	//! \param [out] new_id The newly created cache id.  	//! \return A pointer to the first buffer containing the  	//!  'initial_samples_needed' number of samples. -	sample_t* open(AudioFile* file, size_t initial_samples_needed, int channel, +	sample_t* open(const AudioFile& file, size_t initial_samples_needed, int channel,  	               cacheid_t& new_id);  	//! Get next buffer. @@ -79,7 +79,7 @@ public:  	//! \return A pointer to the buffer.  	sample_t* next(cacheid_t id, size_t &size); -	//! Returns if the next chunk of the supplied id has been read from disk. +	//! Returns true iff the next chunk of the supplied id has been read from disk.  	bool isReady(cacheid_t id);  	//! Unregister cache entry. @@ -105,7 +105,7 @@ public:  private:  	size_t framesize{0}; -	sample_t *nodata{nullptr}; +	sample_t* nodata{nullptr};  	size_t number_of_underruns{0};  	AudioCacheIDManager id_manager; diff --git a/src/audiocacheeventhandler.cc b/src/audiocacheeventhandler.cc index 7322785..6ec68b5 100644 --- a/src/audiocacheeventhandler.cc +++ b/src/audiocacheeventhandler.cc @@ -53,9 +53,7 @@ public:  };  AudioCacheEventHandler::AudioCacheEventHandler(AudioCacheIDManager& id_manager) -	// Hack to be able to forward declare CacheEvent: -	: eventqueue(new std::list<CacheEvent>()) -	, id_manager(id_manager) +	: id_manager(id_manager)  {  } @@ -69,9 +67,6 @@ AudioCacheEventHandler::~AudioCacheEventHandler()  	{  		handleCloseCache(id);  	} - -	// Hack to be able to forward declare CacheEvent: -	delete eventqueue;  }  void AudioCacheEventHandler::start() @@ -119,7 +114,7 @@ void AudioCacheEventHandler::setThreaded(bool threaded)  	this->threaded = threaded;  } -bool AudioCacheEventHandler::getThreaded() const +bool AudioCacheEventHandler::isThreaded() const  {  	return threaded;  } @@ -206,7 +201,7 @@ AudioCacheFile& AudioCacheEventHandler::openFile(const std::string& filename)  void AudioCacheEventHandler::clearEvents()  {  	// Iterate all events ignoring load events and handling close events. -	for(auto& event : *eventqueue) +	for(auto& event : eventqueue)  	{  		if(event.eventType == EventType::Close)  		{ @@ -214,7 +209,7 @@ void AudioCacheEventHandler::clearEvents()  		}  	} -	eventqueue->clear(); +	eventqueue.clear();  }  void AudioCacheEventHandler::handleLoadNextEvent(CacheEvent& cache_event) @@ -263,14 +258,14 @@ void AudioCacheEventHandler::thread_main()  		sem.wait();  		mutex.lock(); -		if(eventqueue->empty()) +		if(eventqueue.empty())  		{  			mutex.unlock();  			continue;  		} -		CacheEvent cache_event = eventqueue->front(); -		eventqueue->pop_front(); +		CacheEvent cache_event = eventqueue.front(); +		eventqueue.pop_front();  		mutex.unlock();  		// TODO: Skip event if cache_event.pos < cache.pos @@ -298,7 +293,7 @@ void AudioCacheEventHandler::pushEvent(CacheEvent& cache_event)  		if(cache_event.eventType == EventType::LoadNext)  		{ -			for(auto& queued_event : *eventqueue) +			for(auto& queued_event : eventqueue)  			{  				if((queued_event.eventType == EventType::LoadNext) &&  				   (cache_event.afile->getFilename() == @@ -318,7 +313,7 @@ void AudioCacheEventHandler::pushEvent(CacheEvent& cache_event)  		if(!found)  		{  			// The event was not already on the list, create a new one. -			eventqueue->push_back(cache_event); +			eventqueue.push_back(cache_event);  		}  	} diff --git a/src/audiocacheeventhandler.h b/src/audiocacheeventhandler.h index daf7bb9..473a010 100644 --- a/src/audiocacheeventhandler.h +++ b/src/audiocacheeventhandler.h @@ -59,7 +59,7 @@ public:  	void setThreaded(bool threaded);  	//! Get current threaded status. -	bool getThreaded() const; +	bool isThreaded() const;  	//! Lock thread mutex.  	//! This methods are supplied to make this class lockable by std::lock_guard @@ -101,7 +101,7 @@ protected:  	std::mutex mutex; -	std::list<CacheEvent>* eventqueue; +	std::list<CacheEvent> eventqueue;  	bool threaded{false};  	Semaphore sem; diff --git a/src/audiocachefile.cc b/src/audiocachefile.cc index 916ecb7..91fcecf 100644 --- a/src/audiocachefile.cc +++ b/src/audiocachefile.cc @@ -34,8 +34,9 @@  #include "audiocache.h" -AudioCacheFile::AudioCacheFile(const std::string& filename) -	: filename(filename) +AudioCacheFile::AudioCacheFile(const std::string& filename, +                               std::vector<sample_t>& read_buffer) +	: filename(filename), read_buffer(read_buffer)  {  	std::memset(&sf_info, 0, sizeof(SF_INFO)); @@ -49,7 +50,7 @@ AudioCacheFile::AudioCacheFile(const std::string& filename)  	if(sf_info.frames == 0)  	{ -		printf("sf_info.frames == 0\n"); +		WARN(cache, "sf_info.frames == 0\n");  	}  } @@ -101,24 +102,18 @@ void AudioCacheFile::readChunk(const CacheChannels& channels,  		size = num_samples;  	} -	static sample_t *read_buffer = nullptr; -	static size_t read_buffer_size = 0; - -	if((size * sf_info.channels) > read_buffer_size) +	if((size * sf_info.channels) > read_buffer.size())  	{ -		delete[] read_buffer; -		read_buffer_size = size * sf_info.channels; -		read_buffer = new sample_t[read_buffer_size]; -		// TODO: This buffer is never free'd on app shutdown. +		read_buffer.resize(size * sf_info.channels);  	} -	size_t read_size = sf_readf_float(fh, read_buffer, size); +	size_t read_size = sf_readf_float(fh, read_buffer.data(), size);  	(void)read_size;  	for(auto it = channels.begin(); it != channels.end(); ++it)  	{  		size_t channel = it->channel; -		sample_t *data = it->samples; +		sample_t* data = it->samples;  		for (size_t i = 0; i < size; ++i)  		{  			data[i] = read_buffer[(i * sf_info.channels) + channel]; @@ -135,25 +130,25 @@ AudioCacheFile& AudioCacheFiles::getFile(const std::string& filename)  {  	std::lock_guard<std::mutex> lock(mutex); -	AudioCacheFile* cacheAudioFile = nullptr; +	AudioCacheFile* cache_audio_file = nullptr;  	auto it = audiofiles.find(filename);  	if(it == audiofiles.end())  	{ -		cacheAudioFile = new AudioCacheFile(filename); -		audiofiles.insert(std::make_pair(filename, cacheAudioFile)); +		cache_audio_file = new AudioCacheFile(filename, read_buffer); +		audiofiles.insert(std::make_pair(filename, cache_audio_file));  	}  	else  	{ -		cacheAudioFile = it->second; +		cache_audio_file = it->second;  	} -	assert(cacheAudioFile); +	assert(cache_audio_file);  	// Increase ref count. -	++cacheAudioFile->ref; +	++cache_audio_file->ref; -	return *cacheAudioFile; +	return *cache_audio_file;  }  void AudioCacheFiles::releaseFile(const std::string& filename) diff --git a/src/audiocachefile.h b/src/audiocachefile.h index 9910563..8e40a2e 100644 --- a/src/audiocachefile.h +++ b/src/audiocachefile.h @@ -29,6 +29,7 @@  #include <string>  #include <list>  #include <map> +#include <vector>  #include <mutex>  #include "mutex.h" @@ -43,7 +44,7 @@ public:  	size_t channel; //< Channel number  	sample_t* samples; //< Sample buffer pointer.  	size_t num_samples; //< Number of samples in the sample buffer -	volatile bool* ready; //< Is set to tru when the loading is done. +	volatile bool* ready; //< Is set to true when the loading is done.  };  using CacheChannels = std::list<CacheChannel>; @@ -56,7 +57,7 @@ class AudioCacheFile {  	friend class TestableAudioCacheFiles;  public:  	//! Create file handle for filename. -	AudioCacheFile(const std::string& filename); +	AudioCacheFile(const std::string& filename, std::vector<sample_t>& read_buffer);  	//! Closes file handle.  	~AudioCacheFile(); @@ -78,6 +79,7 @@ private:  	SNDFILE* fh{nullptr};  	SF_INFO sf_info;  	std::string filename; +	std::vector<sample_t>& read_buffer;  };  class AudioCacheFiles { @@ -95,4 +97,5 @@ public:  protected:  	std::map<std::string, AudioCacheFile*> audiofiles;  	std::mutex mutex; +	std::vector<sample_t> read_buffer;  }; diff --git a/src/audiocacheidmanager.cc b/src/audiocacheidmanager.cc index a3e16a0..444ac38 100644 --- a/src/audiocacheidmanager.cc +++ b/src/audiocacheidmanager.cc @@ -31,7 +31,7 @@  AudioCacheIDManager::~AudioCacheIDManager()  { -	assert(availableids.size() == id2cache.size()); // All ids should be released. +	assert(available_ids.size() == id2cache.size()); // All ids should be released.  }  void AudioCacheIDManager::init(unsigned int capacity) @@ -39,10 +39,10 @@ void AudioCacheIDManager::init(unsigned int capacity)  	std::lock_guard<std::mutex> guard(mutex);  	id2cache.resize(capacity); -	availableids.resize(capacity); +	available_ids.resize(capacity);  	for(size_t i = 0; i < capacity; ++i)  	{ -		availableids[i] = i; +		available_ids[i] = i;  	}  } @@ -65,14 +65,14 @@ cacheid_t AudioCacheIDManager::registerID(const cache_t& cache)  	cacheid_t id = CACHE_NOID; -	if(availableids.empty()) +	if(available_ids.empty())  	{  		return CACHE_DUMMYID;  	}  	else  	{ -		id = availableids.back(); -		availableids.pop_back(); +		id = available_ids.back(); +		available_ids.pop_back();  	}  	assert(id2cache[id].id == CACHE_NOID); // Make sure it is not already in use @@ -91,7 +91,7 @@ void AudioCacheIDManager::releaseID(cacheid_t id)  	id2cache[id].id = CACHE_NOID; -	availableids.push_back(id); +	available_ids.push_back(id);  }  void AudioCacheIDManager::disableActive() diff --git a/src/audiocacheidmanager.h b/src/audiocacheidmanager.h index 70f7ce1..7bf3169 100644 --- a/src/audiocacheidmanager.h +++ b/src/audiocacheidmanager.h @@ -89,5 +89,5 @@ protected:  	std::mutex mutex;  	std::vector<cache_t> id2cache; -	std::vector<cacheid_t> availableids; +	std::vector<cacheid_t> available_ids;  }; diff --git a/src/audiofile.cc b/src/audiofile.cc index e9b5976..b0ad4da 100644 --- a/src/audiofile.cc +++ b/src/audiofile.cc @@ -56,7 +56,7 @@ AudioFile::~AudioFile()  	unload();  } -bool AudioFile::isValid() +bool AudioFile::isValid() const  {  	return this == magic;  } @@ -147,7 +147,7 @@ void AudioFile::load(int num_samples)  	is_loaded = true;  } -bool AudioFile::isLoaded() +bool AudioFile::isLoaded() const  {  	return is_loaded;  } diff --git a/src/audiofile.h b/src/audiofile.h index 3ca8b97..eb9440e 100644 --- a/src/audiofile.h +++ b/src/audiofile.h @@ -45,7 +45,7 @@ public:  	void load(int num_samples = ALL_SAMPLES);  	void unload(); -	bool isLoaded(); +	bool isLoaded() const;  	volatile size_t size{0}; // Full size of the file  	volatile size_t preloadedsize{0}; // Number of samples preloaded (in data) @@ -53,7 +53,7 @@ public:  	std::string filename; -	bool isValid(); +	bool isValid() const;  	Mutex mutex; diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc index a777125..f8f30b8 100644 --- a/src/drumgizmo.cc +++ b/src/drumgizmo.cc @@ -477,59 +477,59 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)  typedef float vNsf __attribute__ ((vector_size(sizeof(sample_t)*N)));  #endif/*SSE*/ -void DrumGizmo::getSamples(int ch, int pos, sample_t *s, size_t sz) +void DrumGizmo::getSamples(int ch, int pos, sample_t* s, size_t sz)  {  	std::list< Event* >::iterator i = activeevents[ch].begin();  	for(; i != activeevents[ch].end(); ++i)  	{  		bool removeevent = false; -		Event *event = *i; +		Event* event = *i;  		Event::type_t type = event->type();  		switch(type) {  		case Event::sample:  			{ -				EventSample *evt = (EventSample *)event; -				AudioFile *af = evt->file; +				EventSample& evt = *static_cast<EventSample*>(event); +				AudioFile& af = *evt.file; -				if(!af->isLoaded() || !af->isValid() || (s == nullptr)) +				if(!af.isLoaded() || !af.isValid() || (s == nullptr))  				{  					removeevent = true;  					break;  				}  				// Don't handle event now is is scheduled for a future iteration? -				if(evt->offset > (pos + sz)) +				if(evt.offset > (pos + sz))  				{  					continue;  				} -				if(evt->cache_id == CACHE_NOID) +				if(evt.cache_id == CACHE_NOID)  				{ -					size_t initial_chunksize = (pos + sz) - evt->offset; -					evt->buffer = audioCache.open(af, initial_chunksize, -					                              af->filechannel, evt->cache_id); -					evt->buffer_size = initial_chunksize; +					size_t initial_chunksize = (pos + sz) - evt.offset; +					evt.buffer = audioCache.open(af, initial_chunksize, +					                              af.filechannel, evt.cache_id); +					evt.buffer_size = initial_chunksize;  				}  				{ -					MutexAutolock l(af->mutex); +					MutexAutolock l(af.mutex);  					size_t n = 0; // default start point is 0.  					// If we are not at offset 0 in current buffer: -					if(evt->offset > (size_t)pos) +					if(evt.offset > (size_t)pos)  					{ -						n = evt->offset - pos; +						n = evt.offset - pos;  					}  					size_t end = sz; // default end point is the end of the buffer.  					// Find the end point intra-buffer -					if((evt->t + end - n) > af->size) +					if((evt.t + end - n) > af.size)  					{ -						end = af->size - evt->t + n; +						end = af.size - evt.t + n;  					}  					// This should not be necessary but make absolutely sure that we do @@ -540,7 +540,7 @@ void DrumGizmo::getSamples(int ch, int pos, sample_t *s, size_t sz)  					}  					size_t t = 0; // Internal buffer counter -					if(evt->rampdown == NO_RAMPDOWN) +					if(evt.rampdown == NO_RAMPDOWN)  					{  #ifdef SSE @@ -548,40 +548,40 @@ void DrumGizmo::getSamples(int ch, int pos, sample_t *s, size_t sz)  						// Force source addr to be 16 byte aligned...  						// (might skip 1 or 2 samples) -						while((size_t)&evt->buffer[t] % 16) +						while((size_t)&evt.buffer[t] % 16)  						{  							++t;  						} -						for(; (n < optend) && (t < evt->buffer_size); n += N) +						for(; (n < optend) && (t < evt.buffer_size); n += N)  						{ -							*(vNsf*)&(s[n]) += *(vNsf*)&(evt->buffer[t]); +							*(vNsf*)&(s[n]) += *(vNsf*)&(evt.buffer[t]);  							t += N;  						}  #endif -						for(; (n < end) && (t < evt->buffer_size); ++n) +						for(; (n < end) && (t < evt.buffer_size); ++n)  						{ -							s[n] += evt->buffer[t]; +							s[n] += evt.buffer[t];  							++t;  						}  					}  					else  					{ // Ramp down in progress. -						for(; (n < end) && (t < evt->buffer_size) && evt->rampdown; ++n) +						for(; (n < end) && (t < evt.buffer_size) && evt.rampdown; ++n)  						{ -							float scale = (float)evt->rampdown/(float)evt->ramp_start; -							s[n] += evt->buffer[t] * scale; +							float scale = (float)evt.rampdown/(float)evt.ramp_start; +							s[n] += evt.buffer[t] * scale;  							++t; -							evt->rampdown--; +							evt.rampdown--;  						}  					}  					// Add internal buffer counter to "global" event counter. -					evt->t += evt->buffer_size; +					evt.t += evt.buffer_size; -					if((evt->t < af->size) && (evt->rampdown != 0)) +					if((evt.t < af.size) && (evt.rampdown != 0))  					{ -						evt->buffer = audioCache.next(evt->cache_id, evt->buffer_size); +						evt.buffer = audioCache.next(evt.cache_id, evt.buffer_size);  					}  					else  					{ @@ -590,7 +590,7 @@ void DrumGizmo::getSamples(int ch, int pos, sample_t *s, size_t sz)  					if(removeevent)  					{ -						audioCache.close(evt->cache_id); +						audioCache.close(evt.cache_id);  					}  				}  			} | 
