From 28b5df96c2fc89652c724e48ad1ce352228450c6 Mon Sep 17 00:00:00 2001
From: Bent Bisballe Nyeng <deva@aasimon.org>
Date: Sun, 13 Mar 2016 17:32:24 +0100
Subject: Only open AudioCacheFile if needed.

---
 src/audiocache.cc             | 20 +++++++++++---------
 src/audiocacheeventhandler.cc | 40 +++++++++++++++++++++++-----------------
 2 files changed, 34 insertions(+), 26 deletions(-)

diff --git a/src/audiocache.cc b/src/audiocache.cc
index 1aa0320..bb53646 100644
--- a/src/audiocache.cc
+++ b/src/audiocache.cc
@@ -121,8 +121,8 @@ sample_t* AudioCache::open(const AudioFile& file, size_t initial_samples_needed,
 	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;
+	// Next potential read from disk will read from this point.
+	c.pos = cropped_size;
 
 	// Only load next buffer if there is more data in the file to be loaded...
 	if(c.pos < file.size)
@@ -160,7 +160,15 @@ sample_t* AudioCache::next(cacheid_t id, size_t& size)
 		if(c.localpos < c.preloaded_samples_size)
 		{
 			sample_t* s = c.preloaded_samples + c.localpos;
+
+			if((c.localpos + framesize) > c.preloaded_samples_size)
+			{
+				// Only a partial frame is returned. Reflect this in the size
+				size = c.preloaded_samples_size - c.localpos;
+			}
+
 			c.localpos += framesize;
+
 			return s;
 		}
 
@@ -196,6 +204,7 @@ sample_t* AudioCache::next(cacheid_t id, size_t& size)
 	c.pos += CHUNKSIZE(framesize);
 
 	// Does the file have remaining unread samples?
+	assert(c.afile); // Assert that we have an audio file.
 	if(c.pos < c.afile->getSize())
 	{
 		// Do we have a back buffer to read into?
@@ -232,13 +241,6 @@ void AudioCache::close(cacheid_t id)
 		return;
 	}
 
-	cache_t& cache = id_manager.getCache(id);
-	if(cache.afile == nullptr)
-	{
-		// The file was never opened. It was played entirely from preloaded data.
-		return;
-	}
-
 	event_handler.pushCloseEvent(id);
 }
 
diff --git a/src/audiocacheeventhandler.cc b/src/audiocacheeventhandler.cc
index c639242..916b04d 100644
--- a/src/audiocacheeventhandler.cc
+++ b/src/audiocacheeventhandler.cc
@@ -213,6 +213,8 @@ void AudioCacheEventHandler::clearEvents()
 
 void AudioCacheEventHandler::handleLoadNextEvent(CacheEvent& cache_event)
 {
+	assert(cache_event.afile); // Assert that we have an audio file
+
 	cache_event.afile->readChunk(cache_event.channels, cache_event.pos,
 	                             chunksize);
 }
@@ -227,7 +229,11 @@ void AudioCacheEventHandler::handleCloseCache(cacheid_t id)
 {
 	auto& cache = id_manager.getCache(id);
 
-	files.releaseFile(cache.afile->getFilename());
+	// Only close the file if we have also opened it.
+	if(cache.afile)
+	{
+		files.releaseFile(cache.afile->getFilename());
+	}
 
 	delete[] cache.front;
 	delete[] cache.back;
@@ -267,12 +273,6 @@ void AudioCacheEventHandler::thread_main()
 		eventqueue.pop_front();
 		mutex.unlock();
 
-		// TODO: Skip event if cache_event.pos < cache.pos
-		//if(!cache_event.active)
-		//{
-		//	continue;
-		//}
-
 		handleEvent(cache_event);
 	}
 }
@@ -294,17 +294,23 @@ void AudioCacheEventHandler::pushEvent(CacheEvent& cache_event)
 		{
 			for(auto& queued_event : eventqueue)
 			{
-				if((queued_event.event_type == EventType::LoadNext) &&
-				   (cache_event.afile->getFilename() ==
-				    queued_event.afile->getFilename()) &&
-				   (cache_event.pos == queued_event.pos))
+				if(queued_event.event_type == EventType::LoadNext)
 				{
-					// Append channel and buffer to the existing event.
-					queued_event.channels.insert(queued_event.channels.end(),
-					                             cache_event.channels.begin(),
-					                             cache_event.channels.end());
-					found = true;
-					break;
+
+					assert(cache_event.afile); // Assert that we have an audio file
+					assert(queued_event.afile); // Assert that we have an audio file
+
+					if((cache_event.afile->getFilename() ==
+					    queued_event.afile->getFilename()) &&
+					   (cache_event.pos == queued_event.pos))
+					{
+						// Append channel and buffer to the existing event.
+						queued_event.channels.insert(queued_event.channels.end(),
+						                             cache_event.channels.begin(),
+						                             cache_event.channels.end());
+						found = true;
+						break;
+					}
 				}
 			}
 		}
-- 
cgit v1.2.3