summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audiocache.cc51
-rw-r--r--src/audiocache.h29
-rw-r--r--src/audiocacheeventhandler.cc82
-rw-r--r--src/audiocacheeventhandler.h22
-rw-r--r--src/audiocachefile.cc3
-rw-r--r--src/audiocachefile.h13
-rw-r--r--src/audiocacheidmanager.cc10
-rw-r--r--src/audiocacheidmanager.h18
8 files changed, 102 insertions, 126 deletions
diff --git a/src/audiocache.cc b/src/audiocache.cc
index 1493e46..237a3ff 100644
--- a/src/audiocache.cc
+++ b/src/audiocache.cc
@@ -42,8 +42,6 @@ AudioCache::~AudioCache()
{
DEBUG(cache, "~AudioCache() pre\n");
- // TODO: Run through all active cacheids and release them/close their files.
-
deinit();
delete[] nodata;
@@ -54,13 +52,13 @@ void AudioCache::init(size_t poolsize)
{
setAsyncMode(true);
- idManager.init(poolsize);
- eventHandler.start();
+ id_manager.init(poolsize);
+ event_handler.start();
}
void AudioCache::deinit()
{
- eventHandler.stop();
+ event_handler.stop();
}
// Invariant: initial_samples_needed < preloaded audio data
@@ -76,7 +74,7 @@ sample_t* AudioCache::open(AudioFile* file, size_t initial_samples_needed,
}
// Register a new id for this cache session.
- id = idManager.registerID({});
+ id = id_manager.registerID({});
// If we are out of available ids we get CACHE_DUMMYID
if(id == CACHE_DUMMYID)
@@ -87,9 +85,9 @@ sample_t* AudioCache::open(AudioFile* file, size_t initial_samples_needed,
}
// Get the cache_t connected with the registered id.
- cache_t& c = idManager.getCache(id);
+ cache_t& c = id_manager.getCache(id);
- c.afile = &eventHandler.openFile(file->filename);
+ c.afile = &event_handler.openFile(file->filename);
c.channel = channel;
// Next call to 'next()' will read from this point.
@@ -124,7 +122,8 @@ sample_t* AudioCache::open(AudioFile* file, size_t initial_samples_needed,
c.back = new sample_t[CHUNKSIZE(framesize)];
}
- eventHandler.pushLoadNextEvent(c.afile, c.channel, c.pos, c.back, &c.ready);
+ event_handler.pushLoadNextEvent(c.afile, c.channel, c.pos,
+ c.back, &c.ready);
}
return c.preloaded_samples; // return preloaded data
@@ -140,7 +139,7 @@ sample_t* AudioCache::next(cacheid_t id, size_t& size)
return nodata;
}
- cache_t& c = idManager.getCache(id);
+ cache_t& c = id_manager.getCache(id);
if(c.preloaded_samples)
{
@@ -172,7 +171,7 @@ sample_t* AudioCache::next(cacheid_t id, size_t& size)
if(!c.ready)
{
// Just return silence.
- ++numberOfUnderruns;
+ ++number_of_underruns;
return nodata;
}
@@ -193,7 +192,8 @@ sample_t* AudioCache::next(cacheid_t id, size_t& size)
c.back = new sample_t[CHUNKSIZE(framesize)];
}
- eventHandler.pushLoadNextEvent(c.afile, c.channel, c.pos, c.back, &c.ready);
+ event_handler.pushLoadNextEvent(c.afile, c.channel, c.pos,
+ c.back, &c.ready);
}
// We should always have a front buffer at this point.
@@ -209,7 +209,7 @@ bool AudioCache::isReady(cacheid_t id)
return true;
}
- cache_t& cache = idManager.getCache(id);
+ cache_t& cache = id_manager.getCache(id);
return cache.ready;
}
@@ -220,7 +220,7 @@ void AudioCache::close(cacheid_t id)
return;
}
- eventHandler.pushCloseEvent(id);
+ event_handler.pushCloseEvent(id);
}
void AudioCache::setFrameSize(size_t framesize)
@@ -229,12 +229,10 @@ void AudioCache::setFrameSize(size_t framesize)
// Make sure the event handler thread is stalled while we set the framesize
// state.
- std::lock_guard<AudioCacheEventHandler> eventHandlerLock(eventHandler);
-
- DEBUG(cache, "A\n");
+ std::lock_guard<AudioCacheEventHandler> event_handler_lock(event_handler);
// NOTE: Not threaded...
- //std::lock_guard<AudioCacheIDManager> idManagerLock(idManager);
+ //std::lock_guard<AudioCacheIDManager> id_manager_lock(id_manager);
if(framesize > this->framesize)
{
@@ -249,11 +247,7 @@ void AudioCache::setFrameSize(size_t framesize)
this->framesize = framesize;
- DEBUG(cache, "B\n");
-
- eventHandler.setChunkSize(CHUNKSIZE(framesize));
-
- DEBUG(cache, "C\n");
+ event_handler.setChunkSize(CHUNKSIZE(framesize));
}
size_t AudioCache::frameSize() const
@@ -263,23 +257,20 @@ size_t AudioCache::frameSize() const
void AudioCache::setAsyncMode(bool async)
{
- // TODO: Clean out read queue.
- // TODO: Block until reader thread is idle, otherwise we might screw up the
- // buffers...?
- eventHandler.setThreaded(async);
+ event_handler.setThreaded(async);
}
bool AudioCache::asyncMode() const
{
- return eventHandler.getThreaded();
+ return event_handler.getThreaded();
}
size_t AudioCache::getNumberOfUnderruns() const
{
- return numberOfUnderruns;
+ return number_of_underruns;
}
void AudioCache::resetNumberOfUnderruns()
{
- numberOfUnderruns = 0;
+ number_of_underruns = 0;
}
diff --git a/src/audiocache.h b/src/audiocache.h
index 06493e6..004fcf8 100644
--- a/src/audiocache.h
+++ b/src/audiocache.h
@@ -39,29 +39,6 @@
#define CHUNK_MULTIPLIER 16
-
-//TODO:
-// 1: Move nodata initialisation to init method.
-// 2: Make semaphore in thread to block init call until thread has been started.
-
-//// next
-// Pre: preloaded contains 2 x framesize. chunk size is framesize.
-// allocate 2 chunks and copy initial_samples_needed to first buffer from
-// preloaded data and enough to fill up the second buffer from preloaded
-// returns the first buffer and its size in &size.
-// get id from "free stack" and store pointers to buffers in id vector.
-// event: open sndfile handle (if not already open) and increase refcount
-
-//// next
-// Return which ever buffer is the front, swap them and add event to load the
-// next chunk.
-
-//// close
-// decrement file handle refcounter and close file if it is 0.
-// free the 2 buffers
-// (do not erase from the id vector), push index to
-// "free stack" for reuse.
-
class AudioCache {
public:
AudioCache() = default;
@@ -129,8 +106,8 @@ public:
private:
size_t framesize{0};
sample_t *nodata{nullptr};
- size_t numberOfUnderruns{0};
+ size_t number_of_underruns{0};
- AudioCacheIDManager idManager;
- AudioCacheEventHandler eventHandler{idManager};
+ AudioCacheIDManager id_manager;
+ AudioCacheEventHandler event_handler{id_manager};
};
diff --git a/src/audiocacheeventhandler.cc b/src/audiocacheeventhandler.cc
index 89eb09e..7322785 100644
--- a/src/audiocacheeventhandler.cc
+++ b/src/audiocacheeventhandler.cc
@@ -52,10 +52,10 @@ public:
CacheChannels channels;
};
-AudioCacheEventHandler::AudioCacheEventHandler(AudioCacheIDManager& idManager)
+AudioCacheEventHandler::AudioCacheEventHandler(AudioCacheIDManager& id_manager)
// Hack to be able to forward declare CacheEvent:
: eventqueue(new std::list<CacheEvent>())
- , idManager(idManager)
+ , id_manager(id_manager)
{
}
@@ -64,8 +64,8 @@ AudioCacheEventHandler::~AudioCacheEventHandler()
// Close all ids already enqueued to be closed.
clearEvents();
- auto activeIDs = idManager.getActiveIDs();
- for(auto id : activeIDs)
+ auto active_ids = id_manager.getActiveIDs();
+ for(auto id : active_ids)
{
handleCloseCache(id);
}
@@ -139,10 +139,10 @@ void AudioCacheEventHandler::pushLoadNextEvent(AudioCacheFile* afile,
size_t pos, sample_t* buffer,
volatile bool* ready)
{
- CacheEvent e;
- e.eventType = EventType::LoadNext;
- e.pos = pos;
- e.afile = afile;
+ CacheEvent cache_event;
+ cache_event.eventType = EventType::LoadNext;
+ cache_event.pos = pos;
+ cache_event.afile = afile;
CacheChannel c;
c.channel = channel;
@@ -151,18 +151,18 @@ void AudioCacheEventHandler::pushLoadNextEvent(AudioCacheFile* afile,
*ready = false;
c.ready = ready;
- e.channels.insert(e.channels.end(), c);
+ cache_event.channels.insert(cache_event.channels.end(), c);
- pushEvent(e);
+ pushEvent(cache_event);
}
void AudioCacheEventHandler::pushCloseEvent(cacheid_t id)
{
- CacheEvent e;
- e.eventType = EventType::Close;
- e.id = id;
+ CacheEvent cache_event;
+ cache_event.eventType = EventType::Close;
+ cache_event.id = id;
- pushEvent(e);
+ pushEvent(cache_event);
}
void AudioCacheEventHandler::setChunkSize(size_t chunksize)
@@ -185,7 +185,7 @@ void AudioCacheEventHandler::setChunkSize(size_t chunksize)
DEBUG(cache, "2)\n");
// Skip all active cacheids and make their buffers point at nodata.
- idManager.disableActive();
+ id_manager.disableActive();
DEBUG(cache, "3)\n");
@@ -217,38 +217,39 @@ void AudioCacheEventHandler::clearEvents()
eventqueue->clear();
}
-void AudioCacheEventHandler::handleLoadNextEvent(CacheEvent& event)
+void AudioCacheEventHandler::handleLoadNextEvent(CacheEvent& cache_event)
{
- event.afile->readChunk(event.channels, event.pos, chunksize);
+ cache_event.afile->readChunk(cache_event.channels, cache_event.pos,
+ chunksize);
}
-void AudioCacheEventHandler::handleCloseEvent(CacheEvent& e)
+void AudioCacheEventHandler::handleCloseEvent(CacheEvent& cache_event)
{
std::lock_guard<std::mutex> lock(mutex);
- handleCloseCache(e.id);
+ handleCloseCache(cache_event.id);
}
void AudioCacheEventHandler::handleCloseCache(cacheid_t cacheid)
{
- auto& cache = idManager.getCache(cacheid);
+ auto& cache = id_manager.getCache(cacheid);
files.releaseFile(cache.afile->getFilename());
delete[] cache.front;
delete[] cache.back;
- idManager.releaseID(cacheid);
+ id_manager.releaseID(cacheid);
}
-void AudioCacheEventHandler::handleEvent(CacheEvent& e)
+void AudioCacheEventHandler::handleEvent(CacheEvent& cache_event)
{
- switch(e.eventType)
+ switch(cache_event.eventType)
{
case EventType::LoadNext:
- handleLoadNextEvent(e);
+ handleLoadNextEvent(cache_event);
break;
case EventType::Close:
- handleCloseEvent(e);
+ handleCloseEvent(cache_event);
break;
}
}
@@ -268,25 +269,25 @@ void AudioCacheEventHandler::thread_main()
continue;
}
- CacheEvent e = eventqueue->front();
+ CacheEvent cache_event = eventqueue->front();
eventqueue->pop_front();
mutex.unlock();
- // TODO: Skip event if e.pos < cache.pos
- //if(!e.active)
+ // TODO: Skip event if cache_event.pos < cache.pos
+ //if(!cache_event.active)
//{
// continue;
//}
- handleEvent(e);
+ handleEvent(cache_event);
}
}
-void AudioCacheEventHandler::pushEvent(CacheEvent& event)
+void AudioCacheEventHandler::pushEvent(CacheEvent& cache_event)
{
if(!threaded)
{
- handleEvent(event);
+ handleEvent(cache_event);
return;
}
@@ -295,18 +296,19 @@ void AudioCacheEventHandler::pushEvent(CacheEvent& event)
bool found = false;
- if(event.eventType == EventType::LoadNext)
+ if(cache_event.eventType == EventType::LoadNext)
{
- for(auto& queuedEvent : *eventqueue)
+ for(auto& queued_event : *eventqueue)
{
- if((queuedEvent.eventType == EventType::LoadNext) &&
- (event.afile->getFilename() == queuedEvent.afile->getFilename()) &&
- (event.pos == queuedEvent.pos))
+ if((queued_event.eventType == EventType::LoadNext) &&
+ (cache_event.afile->getFilename() ==
+ queued_event.afile->getFilename()) &&
+ (cache_event.pos == queued_event.pos))
{
// Append channel and buffer to the existing event.
- queuedEvent.channels.insert(queuedEvent.channels.end(),
- event.channels.begin(),
- event.channels.end());
+ queued_event.channels.insert(queued_event.channels.end(),
+ cache_event.channels.begin(),
+ cache_event.channels.end());
found = true;
break;
}
@@ -316,7 +318,7 @@ void AudioCacheEventHandler::pushEvent(CacheEvent& event)
if(!found)
{
// The event was not already on the list, create a new one.
- eventqueue->push_back(event);
+ eventqueue->push_back(cache_event);
}
}
diff --git a/src/audiocacheeventhandler.h b/src/audiocacheeventhandler.h
index 733c80e..daf7bb9 100644
--- a/src/audiocacheeventhandler.h
+++ b/src/audiocacheeventhandler.h
@@ -43,7 +43,7 @@ class AudioCacheEventHandler
: protected Thread
{
public:
- AudioCacheEventHandler(AudioCacheIDManager& idManager);
+ AudioCacheEventHandler(AudioCacheIDManager& id_manager);
~AudioCacheEventHandler();
//! Start event handler thread.
@@ -80,22 +80,26 @@ public:
AudioCacheFile& openFile(const std::string& filename);
protected:
- AudioCacheFiles files;
+ void clearEvents();
- std::mutex mutex;
+ void handleLoadNextEvent(CacheEvent& cache_event);
- void clearEvents();
+ //! Lock the mutex and calls handleCloseCache
+ void handleCloseEvent(CacheEvent& cache_event);
- void handleLoadNextEvent(CacheEvent& e);
- void handleCloseEvent(CacheEvent& e);
+ //! Close decrease the file ref and release the cache id.
void handleCloseCache(cacheid_t cacheid);
- void handleEvent(CacheEvent& e);
+ void handleEvent(CacheEvent& cache_event);
// From Thread
void thread_main() override;
- void pushEvent(CacheEvent& e);
+ void pushEvent(CacheEvent& cache_event);
+
+ AudioCacheFiles files;
+
+ std::mutex mutex;
std::list<CacheEvent>* eventqueue;
@@ -104,7 +108,7 @@ protected:
Semaphore sem_run;
bool running{false};
- AudioCacheIDManager& idManager;
+ AudioCacheIDManager& id_manager;
size_t chunksize{1024};
};
diff --git a/src/audiocachefile.cc b/src/audiocachefile.cc
index 039a46d..916ecb7 100644
--- a/src/audiocachefile.cc
+++ b/src/audiocachefile.cc
@@ -88,7 +88,8 @@ void AudioCacheFile::readChunk(const CacheChannels& channels,
if((int)pos > sf_info.frames)
{
- printf("pos (%d) > sf_info.frames (%d)\n", (int)pos, (int)sf_info.frames);
+ WARN(cache, "pos (%d) > sf_info.frames (%d)\n",
+ (int)pos, (int)sf_info.frames);
return;
}
diff --git a/src/audiocachefile.h b/src/audiocachefile.h
index 2f988e2..9910563 100644
--- a/src/audiocachefile.h
+++ b/src/audiocachefile.h
@@ -29,20 +29,21 @@
#include <string>
#include <list>
#include <map>
+
#include <mutex>
+#include "mutex.h"
#include <sndfile.h>
#include <audiotypes.h>
-#include "mutex.h"
-
+//! Channel data container in the cache world.
class CacheChannel {
public:
- size_t channel;
- sample_t* samples;
- size_t num_samples;
- volatile bool* ready;
+ 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.
};
using CacheChannels = std::list<CacheChannel>;
diff --git a/src/audiocacheidmanager.cc b/src/audiocacheidmanager.cc
index 87aaa41..a3e16a0 100644
--- a/src/audiocacheidmanager.cc
+++ b/src/audiocacheidmanager.cc
@@ -29,10 +29,6 @@
#include <limits>
#include <assert.h>
-AudioCacheIDManager::AudioCacheIDManager()
-{
-}
-
AudioCacheIDManager::~AudioCacheIDManager()
{
assert(availableids.size() == id2cache.size()); // All ids should be released.
@@ -114,15 +110,15 @@ void AudioCacheIDManager::disableActive()
std::vector<cacheid_t> AudioCacheIDManager::getActiveIDs()
{
- std::vector<cacheid_t> activeIDs;
+ std::vector<cacheid_t> active_ids;
for(auto& cache : id2cache)
{
if(cache.id != CACHE_NOID)
{
- activeIDs.push_back(cache.id);
+ active_ids.push_back(cache.id);
}
}
- return activeIDs;
+ return active_ids;
}
diff --git a/src/audiocacheidmanager.h b/src/audiocacheidmanager.h
index 1975973..70f7ce1 100644
--- a/src/audiocacheidmanager.h
+++ b/src/audiocacheidmanager.h
@@ -60,21 +60,25 @@ typedef struct {
class AudioCacheIDManager {
friend class AudioCacheEventHandler;
public:
- AudioCacheIDManager();
+ AudioCacheIDManager() = default;
~AudioCacheIDManager();
+ //! Initialise id lists with specified capacity.
+ //! Exceeding this capacity will result in CACHE_DUMMYID on calls to
+ //! registerID.
void init(unsigned int capacity);
- // #thread safe
- // #hard real-time safe
+ //! Get the cache object connected with the specified cacheid.
+ //! Note: The cacheid MUST be active.
cache_t& getCache(cacheid_t id);
- // Thread safe
- // Real-time safe
+ //! 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);
- // Thread safe
- // Real-time safe
+ //! Release a cache object and its correseponding cacheid.
+ //! After this call the cacheid can no longer be used.
void releaseID(cacheid_t id);
protected: