diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/audiooutputengine.h | 5 | ||||
| -rw-r--r-- | src/cachemanager.cc | 51 | ||||
| -rw-r--r-- | src/cachemanager.h | 9 | ||||
| -rw-r--r-- | src/drumgizmo.cc | 60 | ||||
| -rw-r--r-- | src/drumgizmo.h | 17 | ||||
| -rw-r--r-- | src/drumkitloader.cc | 12 | ||||
| -rw-r--r-- | src/drumkitloader.h | 5 | 
7 files changed, 93 insertions, 66 deletions
| diff --git a/src/audiooutputengine.h b/src/audiooutputengine.h index 7f15e49..8b2b768 100644 --- a/src/audiooutputengine.h +++ b/src/audiooutputengine.h @@ -50,11 +50,6 @@ public:    // Reimplement this if you wish to use internal buffer directly.    virtual sample_t *getBuffer(int ch) { return NULL; } - -  /* -   * Overload this method to force engine to use different buffer size. -   */ -  virtual size_t getBufferSize() { return 1024; }  };  #endif/*__DRUMGIZMO_AUDIOOUTPUTENGINE_H__*/ diff --git a/src/cachemanager.cc b/src/cachemanager.cc index 61fdb3e..4053f05 100644 --- a/src/cachemanager.cc +++ b/src/cachemanager.cc @@ -28,15 +28,16 @@  #include <string.h>  #include <stdio.h> +#include <assert.h>  #include <sndfile.h>  #include <hugin.hpp> -static sample_t nodata[FRAMESIZE]; -  #define	BUFFER_SIZE	4092 +#define CHUNKSIZE(x) (x * CHUNK_MULTIPLIER) +  static size_t readChunk(std::string filename, int filechannel, size_t pos,                          size_t num_samples, sample_t* buf)  { @@ -84,21 +85,22 @@ static size_t readChunk(std::string filename, int filechannel, size_t pos,    return size;  } -CacheManager::CacheManager() {} +CacheManager::CacheManager() +  : framesize(0) +  , nodata(NULL) +{ +}  CacheManager::~CacheManager()  {    deinit(); +  delete[] nodata;  }  void CacheManager::init(size_t poolsize, bool threaded)  {    this->threaded = threaded; -  for(size_t i = 0; i < FRAMESIZE; i++) { -    nodata[i] = 0; -  } -    id2cache.resize(poolsize);    for(size_t i = 0; i < poolsize; i++) {      availableids.push_back(i); @@ -137,6 +139,7 @@ sample_t *CacheManager::open(AudioFile *file, size_t initial_samples_needed,    }    if(id == CACHE_DUMMYID) { +    assert(nodata);      return nodata;    } @@ -145,10 +148,10 @@ sample_t *CacheManager::open(AudioFile *file, size_t initial_samples_needed,    c.channel = channel;    c.pos = initial_samples_needed;    c.localpos = 0; -  c.front = new sample_t[CHUNKSIZE]; -  c.back = new sample_t[CHUNKSIZE]; +  c.front = new sample_t[CHUNKSIZE(framesize)]; +  c.back = new sample_t[CHUNKSIZE(framesize)]; -  size_t size = CHUNKSIZE; +  size_t size = CHUNKSIZE(framesize);    if(size > (file->preloadedsize - c.pos)) size = (file->preloadedsize - c.pos);    memcpy(c.front, c.file->data + c.pos, size * sizeof(sample_t));    c.ready = false; @@ -174,21 +177,22 @@ sample_t *CacheManager::open(AudioFile *file, size_t initial_samples_needed,  sample_t *CacheManager::next(cacheid_t id, size_t &size)   { -  size = FRAMESIZE; +  size = framesize;    if(id == CACHE_DUMMYID) { +    assert(nodata);      return nodata;    }    cache_t& c = id2cache[id]; -  if(c.localpos < CHUNKSIZE) { +  if(c.localpos < CHUNKSIZE(framesize)) {      sample_t *s = c.front + c.localpos;      c.localpos += size;      return s;    }    if(!c.ready) { -    printf("#%d: NOT READY!\n", id); // TODO: Count and show in UI? +    //printf("#%d: NOT READY!\n", id); // TODO: Count and show in UI?    }    // Swap buffers @@ -198,7 +202,7 @@ sample_t *CacheManager::next(cacheid_t id, size_t &size)    c.localpos = size; // Next time we go here we have already read the first frame. -  c.pos += CHUNKSIZE; +  c.pos += CHUNKSIZE(framesize);    if(c.pos < c.file->size) {      cevent_t e = createLoadNextEvent(c.file, c.channel, c.pos, c.back); @@ -220,17 +224,28 @@ void CacheManager::close(cacheid_t id)    pushEvent(e);  } +void CacheManager::setFrameSize(size_t framesize) +{ +  this->framesize = framesize; +  delete[] nodata; +  nodata = new sample_t[framesize]; + +  for(size_t i = 0; i < framesize; i++) { +    nodata[i] = 0; +  } +} +  void CacheManager::handleLoadNextEvent(cevent_t &e)   {  #if 0 // memcpy -  size_t size = CHUNKSIZE; +  size_t size = CHUNKSIZE(framesize);    if(size > (e.file->size - e.pos)) {      size = (e.file->size - e.pos);    }    memcpy(e.buffer, e.file->data + e.pos, size * sizeof(sample_t));  #elif 1 // diskread -  //memset(e.buffer, 0, CHUNKSIZE * sizeof(sample_t)); -  readChunk(e.file->filename, e.channel, e.pos, CHUNKSIZE, e.buffer); +  //memset(e.buffer, 0, CHUNKSIZE(framesize) * sizeof(sample_t)); +  readChunk(e.file->filename, e.channel, e.pos, CHUNKSIZE(framesize), e.buffer);  #endif    *e.ready = true;  } @@ -246,7 +261,7 @@ void CacheManager::handleCloseEvent(cevent_t &e)      availableids.push_back(e.id);    } -  // TODO: Count down ref coutner on c.file and close it if 0. +  // TODO: Count down ref counter on c.file and close it if 0.  } diff --git a/src/cachemanager.h b/src/cachemanager.h index f2c0122..d98d66c 100644 --- a/src/cachemanager.h +++ b/src/cachemanager.h @@ -41,9 +41,7 @@  #define CACHE_DUMMYID -2  #define CACHE_NOID -1 -#define FRAMESIZE 2048 -#define CHUNKSIZE (FRAMESIZE * 16) -#define PRELOADSIZE (FRAMESIZE + CHUNKSIZE) +#define CHUNK_MULTIPLIER 16  class AudioFile;  typedef int cacheid_t; @@ -131,10 +129,15 @@ public:     */    void close(cacheid_t id); +  void setFrameSize(size_t framesize); +    ///! Internal thread main method - needs to be public.    void thread_main();  private: +  size_t framesize; +  sample_t *nodata; +    typedef struct {      AudioFile *file;      size_t channel; diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc index fb4f042..8661232 100644 --- a/src/drumgizmo.cc +++ b/src/drumgizmo.cc @@ -46,8 +46,11 @@  #include "nolocale.h"  DrumGizmo::DrumGizmo(AudioOutputEngine *o, AudioInputEngine *i) -  : MessageReceiver(MSGRCV_ENGINE), -    loader(), oe(o), ie(i) +  : MessageReceiver(MSGRCV_ENGINE) +  , loader() +  , oe(o) +  , ie(i) +  , framesize(0)  {    is_stopping = false;    cacheManager.init(1000, true); // start thread @@ -166,8 +169,30 @@ void DrumGizmo::handleMessage(Message *msg)    }  } +void DrumGizmo::setFrameSize(size_t framesize) +{ +  // If we are resampling override the frame size. +  if(resampler[0].ratio() != 1) { +    framesize = RESAMPLER_INPUT_BUFFER; +  } + +  if(this->framesize != framesize) { +    printf("New framesize: %d\n", framesize); + +    this->framesize = framesize; + +    // Update framesize in drumkitloader and cachemanager: +    loader.setFrameSize(framesize); +    printf("loader.setFrameSize\n"); fflush(stdout); +    cacheManager.setFrameSize(framesize); +    printf("cacheManager.setFrameSize\n"); fflush(stdout); +  } +} +  bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)  { +  setFrameSize(nsamples); +    // Handle engine messages, at most one in each iteration:    handleMessages(1); @@ -355,26 +380,6 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)    return true;  } -void DrumGizmo::run(int endpos) -{ -  size_t pos = 0; -  size_t nsamples = oe->getBufferSize(); -  sample_t *samples = (sample_t *)malloc(nsamples * sizeof(sample_t)); - -  ie->start(); -  oe->start(); - -  while(run(pos, samples, nsamples) == true) { -    pos += nsamples; -    if(endpos != -1 && pos >= (size_t)endpos) break; -  } - -  ie->stop(); -  oe->stop(); - -  free(samples); -} -  #ifdef SSE  #define N 8  typedef float vNsf __attribute__ ((vector_size(sizeof(float)*N))); @@ -383,7 +388,7 @@ typedef float vNsf __attribute__ ((vector_size(sizeof(float)*N)));  void DrumGizmo::getSamples(int ch, int pos, sample_t *s, size_t sz)  {    std::list< Event* >::iterator i = activeevents[ch].begin(); -  while(i != activeevents[ch].end()) { +  for(; i != activeevents[ch].end(); ++i) {      bool removeevent = false;      Event *event = *i; @@ -405,17 +410,12 @@ void DrumGizmo::getSamples(int ch, int pos, sample_t *s, size_t sz)            continue;          } -        size_t buffer_offset = 0; -          if(evt->cache_id == CACHE_NOID) {            size_t initial_chunksize = (pos + sz) - evt->offset;            evt->buffer =              cacheManager.open(af, initial_chunksize, ch, evt->cache_id);            evt->buffer_size = initial_chunksize;          } -        else { -          buffer_offset = evt->offset; -        }          {          MutexAutolock l(af->mutex); @@ -479,7 +479,6 @@ void DrumGizmo::getSamples(int ch, int pos, sample_t *s, size_t sz)        i = activeevents[ch].erase(i);        continue;      } -    i++;    }  } @@ -500,6 +499,9 @@ void DrumGizmo::setSamplerate(int samplerate)    for(int i = 0; i < MAX_NUM_CHANNELS; i++) {      resampler[i].setup(kit.samplerate(), Conf::samplerate);    } +  if(resampler[0].ratio() != 1) { +    setFrameSize(RESAMPLER_INPUT_BUFFER); +  }  #endif/*WITH_RESAMPLER*/  } diff --git a/src/drumgizmo.h b/src/drumgizmo.h index f1ec546..807e1e0 100644 --- a/src/drumgizmo.h +++ b/src/drumgizmo.h @@ -24,8 +24,7 @@   *  along with DrumGizmo; if not, write to the Free Software   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.   */ -#ifndef __DRUMGIZMO_DRUMGIZMO_H__ -#define __DRUMGIZMO_DRUMGIZMO_H__ +#pragma once  #include <string>  #include <list> @@ -52,6 +51,7 @@  #define MAX_NUM_CHANNELS 64  #define REFSFILE "refs.conf" +#define RESAMPLER_INPUT_BUFFER 64  class DrumGizmo : public MessageReceiver {  public: @@ -62,10 +62,6 @@ public:    bool init(); -  /** -   * @param endpos number of samples to process, -1 := never stop. -   */ -  void run(int endpos);    bool run(size_t pos, sample_t *samples, size_t nsamples);    void stop(); @@ -79,6 +75,8 @@ public:    int samplerate();    void setSamplerate(int samplerate); +  void setFrameSize(size_t framesize); +  private:    DrumKitLoader loader; @@ -92,14 +90,13 @@ private:    CHResampler resampler[MAX_NUM_CHANNELS];    sample_t resampler_output_buffer[MAX_NUM_CHANNELS][4096]; -  sample_t resampler_input_buffer[MAX_NUM_CHANNELS][64]; +  sample_t resampler_input_buffer[MAX_NUM_CHANNELS][RESAMPLER_INPUT_BUFFER];    std::map<std::string, AudioFile *> audiofiles;    CacheManager cacheManager;    DrumKit kit; -}; - -#endif/*__DRUMGIZMO_DRUMGIZMO_H__*/ +  size_t framesize; +}; diff --git a/src/drumkitloader.cc b/src/drumkitloader.cc index 2b66ae0..413d3f4 100644 --- a/src/drumkitloader.cc +++ b/src/drumkitloader.cc @@ -34,6 +34,7 @@  DrumKitLoader::DrumKitLoader()    : semaphore("drumkitloader") +  , framesize(0)  {    run();    run_semaphore.wait(); // Wait for the thread to actually start. @@ -64,6 +65,13 @@ void DrumKitLoader::skip()    load_queue.clear();  } +void DrumKitLoader::setFrameSize(size_t framesize) +{ +  MutexAutolock l(mutex); +  this->framesize = framesize; +  framesize_semaphore.post(); // Signal that the framesize has been set. +} +  bool DrumKitLoader::isDone()  {    MutexAutolock l(mutex); @@ -120,6 +128,8 @@ void DrumKitLoader::thread_main()    run_semaphore.post(); // Signal that the thread has been started. +  framesize_semaphore.wait(); // Wait until the framesize has been set. +    while(running) {      size_t size;      { @@ -137,7 +147,7 @@ void DrumKitLoader::thread_main()        AudioFile *audiofile = load_queue.front();        load_queue.pop_front();        filename = audiofile->filename; -      audiofile->load(PRELOADSIZE); +      audiofile->load(framesize * CHUNK_MULTIPLIER + framesize);      }      loaded++; diff --git a/src/drumkitloader.h b/src/drumkitloader.h index b4a0a69..22859a0 100644 --- a/src/drumkitloader.h +++ b/src/drumkitloader.h @@ -85,15 +85,20 @@ public:     */    void skip(); +  void setFrameSize(size_t framesize); +  private:    Semaphore run_semaphore;    Semaphore semaphore; +  Semaphore framesize_semaphore;    Mutex mutex;  	volatile bool running{false};    std::list<AudioFile*> load_queue;  	size_t total_num_audiofiles{0};  	size_t fraction{1};  	size_t loaded{0}; + +	size_t framesize{0};  };  #endif/*__DRUMGIZMO_DRUMKITLOADER_H__*/ | 
