summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Suhr Christensen <jsc@umbraculum.org>2015-04-10 16:28:03 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2016-01-20 13:22:07 +0100
commit99db25aae3c8f06b9bb1a17865e344cfe559b47e (patch)
tree31a894019a7514e9f9deb95e431880e61eb966b9
parent88cc4f41efcca827c22aab09e83efe729c89bc9b (diff)
Added unit test shell for cachemanager. Added cache manager logic - still needing audio related code.
-rw-r--r--src/Makefile.am4
-rw-r--r--src/Makefile.am.drumgizmo3
-rw-r--r--src/audiofile.h2
-rw-r--r--src/cachemanager.cc107
-rw-r--r--src/cachemanager.h71
-rw-r--r--test/Makefile.am13
6 files changed, 175 insertions, 25 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index df9f4ca..cb44909 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -9,6 +9,7 @@ EXTRA_DIST = \
channelmixer.h \
chresampler.h \
configuration.h \
+ cachemanager.h \
configparser.h \
drumgizmo.h \
drumkit.h \
@@ -39,6 +40,7 @@ EXTRA_DIST = \
audioinputenginemidi.cc \
audiooutputengine.cc \
beatmapper.cc \
+ cachemanager.cc \
channel.cc \
channelmixer.cc \
chresampler.cc \
@@ -63,4 +65,4 @@ EXTRA_DIST = \
semaphore.cc \
thread.cc \
velocity.cc \
- versionstr.cc \ No newline at end of file
+ versionstr.cc
diff --git a/src/Makefile.am.drumgizmo b/src/Makefile.am.drumgizmo
index 1a3c857..ee09445 100644
--- a/src/Makefile.am.drumgizmo
+++ b/src/Makefile.am.drumgizmo
@@ -5,6 +5,7 @@ DRUMGIZMO_SOURCES = \
$(top_srcdir)/src/channelmixer.cc \
$(top_srcdir)/src/chresampler.cc \
$(top_srcdir)/src/configfile.cc \
+ $(top_srcdir)/src/cachemanager.cc \
$(top_srcdir)/src/configuration.cc \
$(top_srcdir)/src/configparser.cc \
$(top_srcdir)/src/drumgizmo.cc \
@@ -28,4 +29,4 @@ DRUMGIZMO_SOURCES = \
$(top_srcdir)/src/velocity.cc \
$(top_srcdir)/src/versionstr.cc
-DRUMGIZMO_LIBS = $(ZITA_LIBS) $(SNDFILE_LIBS) $(EXPAT_LIBS) $(SAMPLERATE_LIBS) \ No newline at end of file
+DRUMGIZMO_LIBS = $(ZITA_LIBS) $(SNDFILE_LIBS) $(EXPAT_LIBS) $(SAMPLERATE_LIBS)
diff --git a/src/audiofile.h b/src/audiofile.h
index 98bf101..5b57db8 100644
--- a/src/audiofile.h
+++ b/src/audiofile.h
@@ -80,7 +80,7 @@ public:
bool isLoaded();
volatile size_t size;
- volatile sample_t *data;
+ sample_t *data;
std::string filename;
diff --git a/src/cachemanager.cc b/src/cachemanager.cc
index 2e9eab9..5e2adf0 100644
--- a/src/cachemanager.cc
+++ b/src/cachemanager.cc
@@ -3,8 +3,8 @@
* cachemanager.cc
*
* Fri Apr 10 10:39:24 CEST 2015
- * Copyright 2015 Bent Bisballe Nyeng
- * deva@aasimon.org
+ * Copyright 2015 Jonas Suhr Christensen
+ * jsc@umbraculum.org
****************************************************************************/
/*
@@ -26,3 +26,106 @@
*/
#include "cachemanager.h"
+#include <stdio.h>
+
+CacheManager::CacheManager()
+{
+}
+
+CacheManager::~CacheManager()
+{
+ wait_stop();
+}
+
+void CacheManager::init(int poolsize)
+{
+ id2cache.resize(poolsize);
+ for(int i = 0; i < poolsize; i++) {
+ availableids.push_back(i);
+ }
+
+ running = true;
+ run();
+}
+
+// Invariant: initial_samples_needed < preloaded audio data
+sample_t *CacheManager::open(AudioFile *file, int initial_samples_needed, int channel, cacheid_t &id)
+{
+ // What if no free ids is available?
+ m_ids.lock();
+ id = availableids.front();
+ availableids.pop_front();
+ m_ids.unlock();
+
+ cache_t c;
+ c.file = file;
+ c.channel = channel;
+ c.pos = initial_samples_needed;
+ // Allocate buffers
+ // Increase audio ref count
+
+ id2cache[id] = c;
+
+ event_t e;
+ e.id = id;
+ pushEvent(e);
+
+ return file->data;
+}
+
+void CacheManager::close(cacheid_t id)
+{
+ m_ids.lock();
+ availableids.push_back(id);
+ m_ids.unlock();
+
+ // Clean cache_t mapped to event
+ // Clean event list for other events mapped to this id?
+ // Maybe we need an event for this, that we can push in front of eventqueue (con: we dont read from disk when doing this stuff).
+ // Decrement audiofile ref count
+}
+
+sample_t *CacheManager::next(cacheid_t id, size_t &size)
+{
+ sample_t *s = NULL;
+ return s;
+}
+
+void CacheManager::loadNext(cacheid_t id)
+{
+ printf("Loading next...\n");
+
+ // If more is left of file
+ if(false) {
+ event_t e;
+ e.id = id;
+ pushEvent(e);
+ }
+}
+
+void CacheManager::thread_main()
+{
+ while(running) {
+ sem.wait();
+
+ m_events.lock();
+ if(eventqueue.empty()) {
+ event_t e = eventqueue.front();
+ eventqueue.pop_front();
+ m_events.unlock();
+
+ loadNext(e.id);
+ }
+ else {
+ m_events.unlock();
+ }
+ }
+}
+
+void CacheManager::pushEvent(event_t e)
+{
+ // Check that if event should be merged (Maybe by event queue (ie. push in front).
+ m_events.lock();
+ eventqueue.push_back(e);
+ m_events.unlock();
+}
diff --git a/src/cachemanager.h b/src/cachemanager.h
index ed89d12..e170bf4 100644
--- a/src/cachemanager.h
+++ b/src/cachemanager.h
@@ -3,8 +3,8 @@
* cachemanager.h
*
* Fri Apr 10 10:39:24 CEST 2015
- * Copyright 2015 Bent Bisballe Nyeng
- * deva@aasimon.org
+ * Copyright 2015 Jonas Suhr Christensen
+ * jsc@umbraculum.org
****************************************************************************/
/*
@@ -29,18 +29,28 @@
#include <string>
#include <list>
+#include <vector>
+#include "thread.h"
+#include "semaphore.h"
+#include "mutex.h"
+
+#include "audiotypes.h"
+#include "audiofile.h"
+
+#define CACHEMANAGER_NOID -1;
class AudioFile;
+typedef int cacheid_t;
-class CacheManager {
+class CacheManager : public Thread {
public:
+ CacheManager();
+ ~CacheManager();
- class Request {
- public:
- std::string filename;
- std::map<unsigned int, void*> targets;
- size_t pos;
- };
+ void init(int poolsize);
+ void deinit();
+
+ void thread_main();
// Pre: preloaded contains 2 x framesize. chunk size is framesize.
// allocate 2 chunks and copy initial_samples_needed to first buffer from
@@ -48,17 +58,17 @@ public:
// 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
- sample_t *hello(AudioFile *file, int initial_samples_needed, int channel, id_t &new_id);
+ sample_t *open(AudioFile *file, int initial_samples_needed, int channel, cacheid_t &new_id);
// Return which ever buffer is the front, swap them and add event to load the
// next chunk.
- sample_t *getNextBuffer(id_t id, size_t &size);
+ sample_t *next(cacheid_t id, size_t &size);
// 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.
- void goodbye(id_t id);
+ void close(cacheid_t id);
// id vector:
// {
@@ -70,15 +80,38 @@ public:
// }
private:
- class File {
- public:
- sndfile_t *handle;
- int refcounter;
- };
- std::list<Request> requests;
- std::map<AudioFile *, File>
+ void pushEvent();
+
+ typedef struct {
+ AudioFile *file;
+ int channel;
+ size_t pos;
+ void *a;
+ void *b;
+ } cache_t;
+
+ typedef struct {
+ cacheid_t id;
+ } event_t;
+
+ void loadNext(cacheid_t id);
+ void pushEvent(event_t e);
+ cacheid_t leaseId();
+ cacheid_t releaseId();
+
+ // Protected by mutex
+ std::list<event_t> eventqueue;
+ std::list<cacheid_t> availableids;
+ std::vector<cache_t> id2cache;
+
+ Mutex m_events;
+ Mutex m_ids;
+ Mutex m_caches;
+
+ Semaphore sem;
+ int running;
};
#endif/*__DRUMGIZMO_CACHEMANAGER_H__*/
diff --git a/test/Makefile.am b/test/Makefile.am
index 29ab4b1..2c2ab8d 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,7 +1,7 @@
# Rules for the test code (use `make check` to execute)
include $(top_srcdir)/src/Makefile.am.drumgizmo
-TESTS = resource engine gui resampler lv2 configfile
+TESTS = resource engine cache gui resampler lv2 configfile
check_PROGRAMS = $(TESTS)
@@ -26,6 +26,17 @@ engine_SOURCES = \
test.cc \
engine.cc
+cache_CXXFLAGS = -DOUTPUT=\"cache\" $(CPPUNIT_CFLAGS) \
+ -I$(top_srcdir)/src -I$(top_srcdir)/include \
+ -I$(top_srcdir)/hugin -DDISABLE_HUGIN
+cache_CFLAGS = -DDISABLE_HUGIN
+cache_LDFLAGS = $(CPPUNIT_LIBS) $(DRUMGIZMO_LIBS) $(PTHREAD_LIBS)
+cache_SOURCES = \
+ $(DRUMGIZMO_SOURCES) \
+ $(top_srcdir)/hugin/hugin.c \
+ test.cc \
+ cache.cc
+
gui_CXXFLAGS = -DOUTPUT=\"gui\" $(CPPUNIT_CFLAGS)
gui_LDFLAGS = $(CPPUNIT_LIBS)
gui_SOURCES = \