diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.am | 4 | ||||
| -rw-r--r-- | src/Makefile.am.drumgizmo | 3 | ||||
| -rw-r--r-- | src/audiofile.h | 2 | ||||
| -rw-r--r-- | src/cachemanager.cc | 107 | ||||
| -rw-r--r-- | src/cachemanager.h | 71 | 
5 files changed, 163 insertions, 24 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__*/ | 
