diff options
| m--------- | hugin | 0 | ||||
| -rw-r--r-- | src/audiofile.cc | 120 | ||||
| -rw-r--r-- | src/audiofile.h | 49 | ||||
| -rw-r--r-- | src/drumgizmo.cc | 15 | ||||
| -rw-r--r-- | src/drumkitloader.cc | 126 | ||||
| -rw-r--r-- | src/drumkitloader.h | 7 | 
6 files changed, 270 insertions, 47 deletions
| diff --git a/hugin b/hugin -Subproject 782fe184b558070bca926bdeb38c48ea1657854 +Subproject 2630860e6bc935c3daacec186e080eddcc79fe3 diff --git a/src/audiofile.cc b/src/audiofile.cc index 5a9cdb5..c9641dc 100644 --- a/src/audiofile.cc +++ b/src/audiofile.cc @@ -33,15 +33,23 @@  #include <hugin.hpp> +#define LAZYLOAD +  AudioFile::AudioFile(std::string filename)  {    is_loaded = false;    //printf("new AudioFile %p\n", this);    this->filename = filename; +  locked = false;    data = NULL;    size = 0; - +//#ifdef LAZY_LOAD   +  fh = NULL; +  preloaded_data = NULL; +  completely_loaded = false; +//#endif/*LAZYLOAD*/ +  ref_count = 0;    magic = this;    //load(); @@ -61,15 +69,116 @@ bool AudioFile::isValid()  void AudioFile::unload()  { -  if(data) { +  if(data == preloaded_data) {      delete data;      data = NULL;      size = 0;    } +  else { +    size = 0; +    delete data; +    data = NULL; +    delete preloaded_data; +    preloaded_data = NULL; +  } +  sf_close(this->fh); +} + +#define SIZE 512*4  +void AudioFile::init() { +  printf("Initializing %p\n", this); +  if(data) {  +    printf("\t already initialized\n"); +    return; +  } + +  SF_INFO sf_info; +  SNDFILE *fh = sf_open(filename.c_str(), SFM_READ, &sf_info); +  if(!fh) { +    printf("SNDFILE Error (%s): %s\n", filename.c_str(), sf_strerror(fh)); +    return; +  } +  +  int size = SIZE; + +  sample_t* data = new sample_t[size]; +   +  size = sf_read_float(fh, data, size);  +   +  printf("Lazy loaded %d samples\n", size); +  sf_close(fh); + +  mutex.lock(); +  this->data = data; +  this->size = size; +  this->preloaded_data = data; +  this->is_loaded = true; +  this->fh = fh; +//  if(sf_info.frames <= size) { +//    printf("Sample completely loaded\n"); +//    completely_loaded = true; +//  } +  mutex.unlock(); +} + +void AudioFile::loadNext() +{ +  if(this->data != this->preloaded_data) { +    printf("Already completely loaded %p\n", this); +    return; +  } + +  SF_INFO sf_info; +  SNDFILE *fh = sf_open(filename.c_str(), SFM_READ, &sf_info); +//  SF_INFO sf_info = this->sf_info; +//  SNDFILE *fh = this->fh; +  if(!fh) { +    printf("SNDFILE Error (%s): %s\n", filename.c_str(), sf_strerror(fh)); +    return; +  } + +//  sf_seek(fh, 0, SEEK_SET) ; +  +  int size = sf_info.frames; + +  sample_t* data = new sample_t[size]; +   +  size = sf_read_float(fh, data, size);  +   +  printf("Finished loading %d samples %p\n", size, this); +  sf_close(fh); + +  mutex.lock(); +  this->data = data; +  this->size = size; +  mutex.unlock(); +} + +void AudioFile::reset() { +  printf("Resetting audio file %p\n", this); +  if(this->data == this->preloaded_data) { +     printf("\tNot completely loaded - skipping %p\n", this); +     return; +  } + +  mutex.lock(); +  sample_t* old_data = data; +  this->size = SIZE; +  this->data = this->preloaded_data; +//  if() { +    printf("Deleting data %p\n", this); +    delete old_data;  +//  } +  mutex.unlock();  }  void AudioFile::load()  { +#ifdef LAZYLOAD +  init(); +  return; +#endif +    if(data) return;    SF_INFO sf_info; @@ -78,11 +187,14 @@ void AudioFile::load()      printf("SNDFILE Error (%s): %s\n", filename.c_str(), sf_strerror(fh));      return;    } -     +     size = sf_info.frames; +    data = new sample_t[size]; -  sf_read_float(fh, data, size);  +  size = sf_read_float(fh, data, size);  +   +  printf("Loaded %d samples %p\n", size, this);    sf_close(fh); diff --git a/src/audiofile.h b/src/audiofile.h index e4b8410..d203781 100644 --- a/src/audiofile.h +++ b/src/audiofile.h @@ -29,10 +29,44 @@  #include <string>  #include <map> +#include <vector> + +#include <sndfile.h>  #include "mutex.h"  #include "audio.h" +#if 0 +  Plan for lazy loading of audio (Brainstorming) +    * Encapsulate data array? +      - Speed issues? +      - Other suggestion +        * Trigger on read begin and read done +          - readnext(instrument)? +        * size_t current latest loaded sample +        * run in own thread? threads in drumgizmo?? +          - Add soundfile-loader-class which run in its own thread +    * Add pre-loading constant +    * Pointer to pos in audio stream (maybe just last position read) +    * Strategy for how to handle pre-loading of remaining file +      - Is it acceptable only to handle sequential reading of data (no random access)? + +   Thread A                                                  Thread B + +   :preload constant (user defined) +   :speed modifier constant (in which time must  +    sample n be loaded relative to trigger time)  +  ----------                                                           ------ +  | Loader |   <------- Trigger load of InstrumentSample n  --------- | DG   |  +  ----------                                                           ------ +    Load                  (int- right most loaded sample --> If current sample pos loaded +      |            --------- |                                   | +    Wave Into --> | SndFile | <----- Read data (directly from array) +                   ---------   +#endif/*0*/ + +#define LAZYLOAD +  class AudioFile {  public:    AudioFile(std::string filename); @@ -43,12 +77,25 @@ public:    bool isLoaded(); -	sample_t *data;  	size_t size; +	 +  sample_t *data;    std::string filename; +  bool locked; +#ifdef LAZYLOAD +  SF_INFO sf_info; +  SNDFILE *fh; +  bool completely_loaded; +  void init(); +  void reset(); +  void loadNext(); +  sample_t* preloaded_data;  +#endif/*LAZYLOAD*/ +    bool isValid(); +  int ref_count;  private:    void *magic; diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc index 72b3811..df2fd31 100644 --- a/src/drumgizmo.cc +++ b/src/drumgizmo.cc @@ -331,6 +331,10 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)        while(j != kit.channels.end()) {          Channel &ch = *j;          AudioFile *af = s->getAudioFile(&ch); +        if(af) { +          printf("Requesting preparing of audio file\n"); +          loader.prepare(af); +        }          if(af == NULL || !af->isValid()) {            //printf("Missing AudioFile.\n");          } else { @@ -364,6 +368,7 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)      }      if(buf) {        memset(buf, 0, nsamples * sizeof(sample_t)); +              getSamples(c, pos, buf, nsamples);        if(!internal) oe->run(c, samples, nsamples);      } @@ -426,8 +431,9 @@ void DrumGizmo::getSamples(int ch, int pos, sample_t *s, size_t sz)          if(evt->rampdown == NO_RAMPDOWN) {  #ifdef SSE -          size_t optend = ((end - n) / N) * N + n; -          for(; n < optend; n += N) { +//          printf("%d\n", evt->t); fflush(stdout); +         size_t optend = ((end - n) / N) * N + n; +         for(; n < optend; n += N) {              *(vNsf*)&(s[n]) += *(vNsf*)&(af->data[evt->t]);              evt->t += N;            } @@ -446,7 +452,10 @@ void DrumGizmo::getSamples(int ch, int pos, sample_t *s, size_t sz)          } -        if(evt->t >= af->size) removeevent = true; +        if(evt->t >= af->size) {  +          removeevent = true; +          loader.reset(af); +        }        }        break;      } diff --git a/src/drumkitloader.cc b/src/drumkitloader.cc index 79d000a..6516c7d 100644 --- a/src/drumkitloader.cc +++ b/src/drumkitloader.cc @@ -82,14 +82,40 @@ void DrumKitLoader::loadKit(DrumKit *kit)    semaphore.post();  } +void DrumKitLoader::prepare(AudioFile* af) { +  printf("Preparing audiofile %p (%d in queue)\n", af, load_queue.size()); +  mutex.lock(); +  af->ref_count++; +  load_queue.push_back(af); +//  if(ref_count.find(af) == ref_count.end()) { +//    ref_count[af]++; +//  } +//  else { +//    ref_count[af] = 0; +//  } +  mutex.unlock();  +  semaphore.post(); +} + +void DrumKitLoader::reset(AudioFile* af) { +  mutex.lock(); +  af->ref_count--; +  reset_queue.push_back(af); +  mutex.unlock(); +  semaphore.post(); +} +  void DrumKitLoader::thread_main()  {    while(1) {      DEBUG(loader, "before sem\n"); +      semaphore.wait(); +      DEBUG(loader, "after sem\n");      fflush(stdout); +      if(quitit) return;      if(skipit) { @@ -98,66 +124,88 @@ void DrumKitLoader::thread_main()        continue;      } -    unsigned int count = 0; +    if(!load_queue.empty()) { +      printf("Loading remaining of audio file\n");  +      AudioFile* af = load_queue.front(); +      mutex.lock(); +      load_queue.pop_front(); +      mutex.unlock(); +      af->loadNext(); +    } +    else if(!reset_queue.empty()) { +      AudioFile* af = reset_queue.front(); +      mutex.lock(); +      if(af->ref_count <= 0) { +        af->reset(); +        af->ref_count = 0; +      } +      reset_queue.pop_front(); +      mutex.unlock(); +    } +    else { // Initialize drum kit +      printf("Initializing drum kit\n"); +      unsigned int count = 0; -    if(kit && !kit->isValid()) goto finish; +      if(kit && !kit->isValid()) goto finish; -    { // Count total number of files that need loading: -      Instruments::iterator i = kit->instruments.begin(); -      while(i != kit->instruments.end()) { -        Instrument *instr = *i; -        if(instr && !instr->isValid()) goto finish; +      { // Count total number of files that need loading: +        Instruments::iterator i = kit->instruments.begin(); +        while(i != kit->instruments.end()) { +          Instrument *instr = *i; +          if(instr && !instr->isValid()) goto finish; -        count += instr->audiofiles.size(); -        i++; +          count += instr->audiofiles.size(); +          i++; +        }        } -    } -    { // Now actually load them: -      unsigned int loaded = 0; -      Instruments::iterator i = kit->instruments.begin(); -      while(i != kit->instruments.end()) { -        Instrument *instr = *i; +      { // Now actually load them: +        unsigned int loaded = 0; +        Instruments::iterator i = kit->instruments.begin(); +        while(i != kit->instruments.end()) { +          Instrument *instr = *i; -        if(instr && !instr->isValid()) goto finish; +          if(instr && !instr->isValid()) goto finish; -        std::vector<AudioFile*>::iterator a = instr->audiofiles.begin(); -        while(a != instr->audiofiles.end()) { +          std::vector<AudioFile*>::iterator a = instr->audiofiles.begin(); +          while(a != instr->audiofiles.end()) {  #if 0  #ifdef WIN32 -          SleepEx(5000, FALSE); +            SleepEx(5000, FALSE);  #else -          usleep(5000); +            usleep(5000);  #endif/*WIN32*/  #endif -          AudioFile *af = *a; +            AudioFile *af = *a; -          if(af && !af->isValid()) goto finish; +            if(af && !af->isValid()) goto finish; -          af->load(); -          loaded++; +            af->load(); +           +            loaded++; -          LoadStatusMessage *ls = new LoadStatusMessage(); -          ls->number_of_files = count; -          ls->numer_of_files_loaded = loaded; -          ls->current_file = af->filename; -          drumgizmo->sendGUIMessage(ls); +            LoadStatusMessage *ls = new LoadStatusMessage(); +            ls->number_of_files = count; +            ls->numer_of_files_loaded = loaded; +            ls->current_file = af->filename; +            drumgizmo->sendGUIMessage(ls); -          a++; +            a++; -          if(skipit) goto finish; -        } +            if(skipit) goto finish; +          } -        i++; +          i++; +        }        } -    } -    mutex.lock(); -    is_done = true; -    mutex.unlock(); +      mutex.lock(); +      is_done = true; +      mutex.unlock(); -  finish: -    continue; +    finish: +      continue; +    }    }  } diff --git a/src/drumkitloader.h b/src/drumkitloader.h index 50b8236..9d14638 100644 --- a/src/drumkitloader.h +++ b/src/drumkitloader.h @@ -28,6 +28,7 @@  #define __DRUMGIZMO_DRUMKITLOADER_H__  #include <string> +#include <list>  #include "thread.h"  #include "semaphore.h" @@ -43,6 +44,9 @@ public:    ~DrumKitLoader();    void loadKit(DrumKit *kit); +   +  void prepare(AudioFile* af); +  void reset(AudioFile* af);    void thread_main(); @@ -60,6 +64,9 @@ private:    Mutex mutex;    volatile bool quitit;    volatile bool skipit; +  std::list<AudioFile*> load_queue; +  std::list<AudioFile*> reset_queue; +  std::map<AudioFile*, int> ref_count;  };  #endif/*__DRUMGIZMO_DRUMKITLOADER_H__*/ | 
