Changes in / [67b6618:41b985f]


Ignore:
Files:
14 added
10 edited

Legend:

Unmodified
Added
Removed
  • .travis.yml

    r67b6618 r41b985f  
    4242      osx_image: xcode8
    4343      compiler: clang
    44       env: WAFOPTS="--with-target-platform=ios --disable-avcodec --disable-sndfile" AUBIO_NOTESTS=1
     44      env: WAFOPTS="--with-target-platform=ios --disable-avcodec --disable-sndfile --disable-samplerate --disable-rubberband" AUBIO_NOTESTS=1
    4545    - language: C
    4646      os: osx
    4747      osx_image: xcode8
    4848      compiler: clang
    49       env: WAFOPTS="--with-target-platform=iosimulator --disable-avcodec --disable-sndfile" AUBIO_NOTESTS=1
     49      env: WAFOPTS="--enable-fat --disable-avcodec --disable-sndfile --disable-samplerate --disable-rubberband" AUBIO_NOTESTS=1
    5050    - language: C
    5151      os: osx
     
    8181    - libasound2-dev
    8282    - libfftw3-dev
     83    - librubberband-dev
    8384    - sox
    8485
     
    9091       brew install ffmpeg
    9192       brew install libsndfile
     93       brew install libsamplerate
     94       brew install rubberband
    9295       export PATH="$HOME/Library/Python/2.7/bin/:$PATH"
    9396     fi;
  • python/lib/gen_code.py

    r67b6618 r41b985f  
    2020    'method': '"default"',
    2121    'uri': '"none"',
     22    'transpose': '0.',
     23    'maxwrite': 1024,
     24    'maxrequest': 1024,
    2225    }
    2326
     
    8386        'filterbank': 'self->n_filters',
    8487        'tss': 'self->buf_size',
     88        'pitchshift': 'self->hop_size',
     89        'ringbuffer': 'self->maxrequest',
    8590        }
    8691
     
    95100        'wavetable': 'self->hop_size',
    96101        'tss': 'self->buf_size / 2 + 1',
     102        'pitchshift': 'self->hop_size',
     103        'ringbuffer': 'self->maxwrite',
    97104        }
    98105
     
    266273        if p['type'] == 'char_t*':
    267274            return self.check_valid_char(p)
     275        if p['type'] == 'smpl_t':
     276            return self.check_valid_smpl(p)
    268277        else:
    269278            print ("ERROR, no idea how to check %s for validity" % p['type'])
     
    286295    self->{name} = {defval};
    287296    if ({name} != NULL) {{
     297        self->{name} = {name};
     298    }}
     299""".format(defval = aubiodefvalue[name], name = name)
     300
     301    def check_valid_smpl(self, p):
     302        name = p['name']
     303        return """
     304    self->{name} = {defval};
     305    if ({name} != 0.) {{
    288306        self->{name} = {name};
    289307    }}
  • python/lib/gen_external.py

    r67b6618 r41b985f  
    4040  #'sampler',
    4141  'audio_unit',
     42  'timestretch', # TODO fix parsing of uint_t *read in _do
     43  'sampler', # TODO fix parsing of uint_t *read in _do
     44  'ringbuffer',
    4245  ]
    4346
  • python/lib/moresetuptools.py

    r67b6618 r41b985f  
    115115    packages = ['libavcodec', 'libavformat', 'libavutil', 'libavresample',
    116116                'jack',
    117                 'jack',
    118117                'sndfile',
     118                'samplerate',
     119                'rubberband',
    119120                #'fftw3f',
    120121               ]
     
    136137    if 'samplerate' in ext.libraries:
    137138        ext.define_macros += [('HAVE_SAMPLERATE', 1)]
     139    if 'rubberband' in ext.libraries:
     140        ext.define_macros += [('HAVE_RUBBERBAND', 1)]
    138141    if 'fftw3f' in ext.libraries:
    139142        ext.define_macros += [('HAVE_FFTW3F', 1)]
  • src/aubio.h

    r67b6618 r41b985f  
    218218#include "pitch/pitchspecacf.h"
    219219#include "tempo/beattracking.h"
     220#include "effects/pitchshift.h"
     221#include "effects/timestretch.h"
    220222#include "utils/scale.h"
    221223#include "utils/hist.h"
     224#include "utils/ringbuffer.h"
    222225#endif
    223226
  • src/synth/sampler.c

    r67b6618 r41b985f  
    1919*/
    2020
     21#include <assert.h>
    2122
    2223#include "aubio_priv.h"
     
    2425#include "fmat.h"
    2526#include "io/source.h"
     27#include "utils/ringbuffer.h"
    2628#include "synth/sampler.h"
     29
     30#define HAVE_THREADS 1
     31#define READER_THREAD_ON 1
     32#if 0
     33#undef HAVE_THREADS
     34#endif
     35
     36#ifdef HAVE_THREADS
     37#include <pthread.h>
     38#endif
     39
     40typedef enum {
     41  aubio_sampler_reading_from_source,
     42  aubio_sampler_reading_from_table,
     43  aubio_sampler_n_reading_methods
     44} aubio_sampler_reading_method;
     45
     46
     47typedef enum {
     48  aubio_sampler_interp_pitchtime,
     49  aubio_sampler_interp_quad,
     50  aubio_sampler_interp_lin,
     51  aubio_sampler_n_interp_methods
     52} aubio_sampler_interp_method;
    2753
    2854struct _aubio_sampler_t {
    2955  uint_t samplerate;
    3056  uint_t blocksize;
     57  // current reading mode (can be a file or an array)
     58  uint_t reading_from;
     59  // current interpolation mode (can be quadratic, timestretch, ...)
     60  uint_t interp;
     61  aubio_ringbuffer_t *ring;
     62  uint_t perfectloop;
     63  uint_t eof_remaining;
     64  // reading from a table
     65  fvec_t *table;
     66  uint_t table_index;
     67  // reading from a source
    3168  aubio_source_t *source;
     69  const char_t *uri;
     70  uint_t playing;
     71  uint_t opened;
     72  uint_t loop;
     73  uint_t finished;              // end of file was reached
     74  uint_t eof;                   // end of file is now
     75#ifdef HAVE_THREADS
     76  // file reading thread
     77  pthread_t read_thread;
     78  uint_t threaded_read;         // use reading thread?
     79  pthread_mutex_t read_mutex;
     80  pthread_cond_t read_avail;
     81  pthread_cond_t read_request;
     82  uint_t source_blocksize;
    3283  fvec_t *source_output;
    33   fmat_t *source_output_multi;
    34   char_t *uri;
    35   uint_t playing;
     84  fmat_t *source_moutput;
     85  uint_t channels;
     86  // file opening thread
     87  pthread_t open_thread;
     88  pthread_mutex_t open_mutex;
     89  uint_t waited;                // number of frames skipped while opening
     90  const char_t *next_uri;
     91  uint_t open_thread_running;
     92  sint_t available;             // number of samples currently available
     93  uint_t started;               // source warmed up
     94  uint_t read_thread_finish;    // flag to tell reading thread to exit
     95#endif
    3696};
    3797
    38 aubio_sampler_t *new_aubio_sampler(uint_t samplerate, uint_t blocksize)
     98static sint_t aubio_sampler_pull_from_source(aubio_sampler_t *s);
     99
     100static void aubio_sampler_do_eof(aubio_sampler_t *s);
     101
     102static void aubio_sampler_read(aubio_sampler_t *s, fvec_t *output, uint_t *read);
     103static void aubio_sampler_read_from_source(aubio_sampler_t *s, fvec_t *output, uint_t *read);
     104static void aubio_sampler_read_from_table(aubio_sampler_t *s, fvec_t *output, uint_t *read);
     105
     106#ifdef HAVE_THREADS
     107static void *aubio_sampler_openfn(void *p);
     108static void *aubio_sampler_readfn(void *p);
     109static void aubio_sampler_open_opening_thread(aubio_sampler_t *o);
     110static void aubio_sampler_open_reading_thread(aubio_sampler_t *o);
     111static void aubio_sampler_close_opening_thread(aubio_sampler_t *o);
     112static void aubio_sampler_close_reading_thread(aubio_sampler_t *o);
     113#endif
     114
     115aubio_sampler_t *new_aubio_sampler(uint_t blocksize, uint_t samplerate)
    39116{
    40117  aubio_sampler_t *s = AUBIO_NEW(aubio_sampler_t);
     
    45122  s->samplerate = samplerate;
    46123  s->blocksize = blocksize;
    47   s->source_output = new_fvec(blocksize);
    48   s->source_output_multi = new_fmat(4, blocksize);
    49124  s->source = NULL;
    50125  s->playing = 0;
     126  s->loop = 0;
     127  s->uri = NULL;
     128  s->finished = 1;
     129  s->eof = 0;
     130  s->opened = 0;
     131  s->available = 0;
     132
     133  s->threaded_read = 0;
     134  s->perfectloop = 0;
     135#if 0 // naive mode
     136  s->source_blocksize = s->blocksize;
     137#elif 0 // threaded mode, no ringbuffer
     138  s->source_blocksize = s->blocksize;
     139  s->threaded_read = 1;
     140#elif 0 // unthreaded, with ringbuffer
     141  s->source_blocksize = 2048; //32 * s->blocksize;
     142  s->perfectloop = 1;
     143#elif 1 // threaded with ringhbuffer
     144  s->source_blocksize = 2048; //32 * s->blocksize;
     145  s->perfectloop = 1;
     146  s->threaded_read = 1;
     147#endif
     148
     149  if (s->source_blocksize < s->blocksize) {
     150    s->source_blocksize = s->blocksize;
     151  }
     152  // FIXME: perfectloop fails if source_blocksize > 2048 with source_avcodec
     153  //s->source_blocksize = 8192;
     154
     155  if (s->perfectloop || s->source_blocksize != s->blocksize) {
     156    s->ring = new_aubio_ringbuffer(s->source_blocksize * 2, s->blocksize);
     157  }
     158  if (s->threaded_read || s->perfectloop || s->ring)
     159    s->source_output = new_fvec(s->source_blocksize);
     160  //s->channels = 1;
     161  //s->source_moutput = new_fmat(s->source_blocksize, s->channels);
     162
     163#ifdef HAVE_THREADS
     164  aubio_sampler_open_opening_thread(s);
     165
     166  if (s->threaded_read) {
     167    //AUBIO_WRN("sampler: starting reading thread\n");
     168    aubio_sampler_open_reading_thread(s);
     169  }
     170#endif
     171
     172#if 0
     173  s->reading_from = aubio_sampler_reading_from_table;
     174  s->perfectloop = 1;
     175  s->threaded_read = 0;
     176  s->opened = 1;
     177  s->finished = 1;
     178  s->table_index = 0;
     179#endif
     180
    51181  return s;
    52182beach:
     
    55185}
    56186
     187#ifdef HAVE_THREADS
     188void aubio_sampler_open_opening_thread(aubio_sampler_t *s) {
     189  pthread_mutex_init(&s->open_mutex, 0);
     190  s->waited = 0;
     191  s->open_thread = 0;
     192  s->open_thread_running = 0;
     193}
     194
     195void aubio_sampler_open_reading_thread(aubio_sampler_t *s) {
     196  s->read_thread_finish = 0;
     197  pthread_mutex_init(&s->read_mutex, 0);
     198  pthread_cond_init (&s->read_avail, 0);
     199  pthread_cond_init (&s->read_request, 0);
     200  pthread_create(&s->read_thread, 0, aubio_sampler_readfn, s);
     201}
     202
     203void aubio_sampler_close_opening_thread(aubio_sampler_t *o) {
     204  // clean up opening thread
     205  void *threadret;
     206  if (!o->open_thread) return;
     207  pthread_mutex_destroy(&o->open_mutex);
     208  if (o->open_thread_running) {
     209    if (pthread_cancel(o->open_thread)) {
     210      AUBIO_WRN("sampler: cancelling file opening thread failed\n");
     211    }
     212  }
     213  if (o->open_thread && pthread_join(o->open_thread, &threadret)) {
     214    AUBIO_WRN("sampler: joining file opening thread failed\n");
     215  }
     216  pthread_mutex_destroy(&o->open_mutex);
     217  o->open_thread = 0;
     218}
     219
     220void aubio_sampler_close_reading_thread(aubio_sampler_t *o) {
     221  // clean up reading thread
     222  void *threadret;
     223  if (!o->read_thread) return;
     224  o->read_thread_finish = 1;
     225  pthread_cond_signal(&o->read_request);
     226  if (pthread_cancel(o->read_thread)) {
     227    AUBIO_WRN("sampler: cancelling file reading thread failed\n");
     228  }
     229  if (pthread_join(o->read_thread, &threadret)) {
     230    AUBIO_WRN("sampler: joining file reading thread failed\n");
     231  }
     232  pthread_mutex_destroy(&o->read_mutex);
     233  pthread_cond_destroy(&o->read_avail);
     234  pthread_cond_destroy(&o->read_request);
     235  o->read_thread = 0;
     236}
     237#endif
     238
    57239uint_t aubio_sampler_load( aubio_sampler_t * o, const char_t * uri )
    58240{
    59   if (o->source) del_aubio_source(o->source);
    60 
    61   if (o->uri) AUBIO_FREE(o->uri);
    62   o->uri = AUBIO_ARRAY(char_t, strnlen(uri, PATH_MAX));
    63   strncpy(o->uri, uri, strnlen(uri, PATH_MAX));
    64 
    65   o->source = new_aubio_source(uri, o->samplerate, o->blocksize);
    66   if (o->source) return 0;
    67   AUBIO_ERR("sampler: failed loading %s", uri);
    68   return 1;
    69 }
    70 
    71 void aubio_sampler_do ( aubio_sampler_t * o, const fvec_t * input, fvec_t * output)
    72 {
    73   uint_t read = 0, i;
     241  uint_t ret = AUBIO_FAIL;
     242  aubio_source_t *oldsource = o->source, *newsource = NULL;
     243  newsource = new_aubio_source(uri, o->samplerate, o->source_blocksize);
     244  if (newsource) {
     245    uint_t duration = aubio_source_get_duration(newsource);
     246    if (duration < o->blocksize) {
     247      AUBIO_WRN("sampler: %s is %d frames long, but blocksize is %d\n",
     248          uri, duration, o->blocksize);
     249    }
     250    o->source = newsource;
     251    if (oldsource) del_aubio_source(oldsource);
     252    if (o->samplerate == 0) {
     253      o->samplerate = aubio_source_get_samplerate(o->source);
     254    }
     255    o->uri = uri;
     256    o->finished = 0;
     257    o->eof = 0;
     258    o->eof_remaining = 0;
     259    o->opened = 1;
     260    ret = AUBIO_OK;
     261    AUBIO_WRN("sampler: loaded %s\n", uri);
     262    if (o->waited) {
     263      AUBIO_WRN("sampler: %.2fms (%d samples) taken to load %s\n", 1000. *
     264          o->waited / (smpl_t)o->samplerate, o->waited, o->uri);
     265    }
     266  } else {
     267    o->source = NULL;
     268    if (oldsource) del_aubio_source(oldsource);
     269    o->playing = 0;
     270    o->uri = NULL;
     271    o->finished = 1;
     272    o->eof = 0;
     273    o->eof_remaining = 0;
     274    o->opened = 0;
     275    AUBIO_WRN("sampler: failed loading %s\n", uri);
     276  }
     277  if (o->ring) {
     278    //AUBIO_WRN("sampler: resetting ringbuffer\n");
     279    aubio_ringbuffer_reset(o->ring);
     280  }
     281  return ret;
     282}
     283
     284#ifdef HAVE_THREADS
     285static void *aubio_sampler_openfn(void *z) {
     286  aubio_sampler_t *p = z;
     287  uint_t err;
     288  int oldtype;
     289  void *ret;
     290  pthread_setcancelstate(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
     291  pthread_mutex_lock(&p->open_mutex);
     292  p->open_thread_running = 1;
     293  err = aubio_sampler_load(p, p->next_uri);
     294  p->open_thread_running = 0;
     295  pthread_mutex_unlock(&p->open_mutex);
     296  ret = &err;
     297  pthread_exit(ret);
     298}
     299#endif
     300
     301uint_t
     302aubio_sampler_queue(aubio_sampler_t *o, const char_t *uri)
     303{
     304#ifdef HAVE_THREADS
     305  uint_t ret = AUBIO_OK;
     306
     307  if (o->reading_from == aubio_sampler_reading_from_table) {
     308    o->reading_from = aubio_sampler_reading_from_source;
     309    o->opened = 0;
     310    o->finished = 1;
     311  }
     312  /* open uri in open_thread */
     313  if (o->open_thread_running) {
     314    // cancel previous open_thread
     315    if (pthread_cancel(o->open_thread)) {
     316      AUBIO_WRN("sampler: failed queuing %s (cancelling existing open thread failed)\n", uri);
     317      return AUBIO_FAIL;
     318    } else {
     319      AUBIO_WRN("sampler: cancelled queuing %s (queuing %s now)\n",
     320          o->next_uri, uri);
     321    }
     322    o->open_thread_running = 0;
     323  }
     324  void *threadret;
     325  if (o->open_thread && pthread_join(o->open_thread, &threadret)) {
     326    AUBIO_WRN("sampler: joining thread failed\n");
     327  }
     328  if (pthread_mutex_trylock(&o->open_mutex)) {
     329    AUBIO_WRN("sampler: failed queuing %s (locking failed)\n", uri);
     330    ret = AUBIO_FAIL;
     331    goto lock_failed;
     332  }
     333  o->opened = 0; // while opening
     334  o->started = 0;
     335  o->available = 0;
     336  o->next_uri = uri;
     337  o->waited = 0;
     338  if (pthread_create(&o->open_thread, 0, aubio_sampler_openfn, o) != 0) {
     339    AUBIO_ERR("sampler: failed creating opening thread\n");
     340    ret = AUBIO_FAIL;
     341    goto thread_create_failed;
     342  }
     343
     344thread_create_failed:
     345  pthread_mutex_unlock(&o->open_mutex);
     346lock_failed:
     347  if (ret == AUBIO_OK) {
     348    //AUBIO_WRN("sampler: queued %s\n", uri);
     349  } else {
     350    AUBIO_ERR("sampler: queueing %s failed\n", uri);
     351  }
     352  return ret;
     353#else
     354  AUBIO_WRN("sampler: opening %s, not queueing (not compiled with threading)\n", uri);
     355  return aubio_sampler_load(o, uri);
     356#endif
     357}
     358
     359#ifdef HAVE_THREADS
     360
     361uint_t aubio_sampler_reading_from_source_ring_fetch(aubio_sampler_t*s);
     362
     363void *aubio_sampler_readfn(void *z) {
     364  aubio_sampler_t *p = z;
     365  while(1) {
     366    pthread_mutex_lock(&p->read_mutex);
     367    if (p->open_thread_running) {
     368      //AUBIO_WRN("sampler: readfn(): file is being opened\n");
     369      pthread_cond_signal(&p->read_avail);
     370      //pthread_cond_wait(&p->read_request, &p->read_mutex);
     371    } else if (p->opened && !p->started && !p->finished) {
     372      //AUBIO_WRN("sampler: readfn(): file started\n");
     373      if (p->ring) {
     374        p->available = aubio_sampler_reading_from_source_ring_fetch(p);
     375      } else {
     376        p->available = aubio_sampler_pull_from_source(p);
     377        if (p->available < (sint_t)p->source_blocksize)
     378          aubio_sampler_do_eof(p);
     379      }
     380      pthread_cond_signal(&p->read_avail);
     381      if (!p->finished) {
     382        pthread_cond_wait(&p->read_request, &p->read_mutex);
     383      }
     384    } else {
     385      //AUBIO_WRN("sampler: readfn(): idle?\n");
     386      pthread_cond_signal(&p->read_avail);
     387      pthread_cond_wait(&p->read_request, &p->read_mutex);
     388      if (p->read_thread_finish) {
     389        goto done;
     390      }
     391    }
     392    pthread_mutex_unlock(&p->read_mutex);
     393  }
     394done:
     395  //AUBIO_WRN("sampler: exiting reading thread\n");
     396  pthread_mutex_unlock(&p->read_mutex);
     397  pthread_exit(NULL);
     398}
     399#endif
     400
     401void
     402aubio_sampler_read(aubio_sampler_t *s, fvec_t *output, uint_t *read) {
     403  if (s->reading_from == aubio_sampler_reading_from_source) {
     404    aubio_sampler_read_from_source(s, output, read);
     405  } else if (s->reading_from == aubio_sampler_reading_from_table) {
     406    aubio_sampler_read_from_table(s, output, read);
     407  }
     408}
     409
     410static void
     411aubio_sampler_reading_from_source_naive(aubio_sampler_t *s, fvec_t * output,
     412    uint_t *read)
     413{
     414  // directly read from disk
     415  //aubio_source_do(s->source, output, read);
     416  s->source_output = output;
     417  *read = aubio_sampler_pull_from_source(s);
     418  if (*read < s->source_blocksize) {
     419    //AUBIO_WRN("sampler: calling go_eof in _read_from_source()\n");
     420    aubio_sampler_do_eof(s);
     421  }
     422}
     423
     424uint_t
     425aubio_sampler_reading_from_source_ring_fetch(aubio_sampler_t*s) {
     426  // read source_blocksize (> blocksize) at once
     427  int ring_avail = aubio_ringbuffer_get_available(s->ring);
     428  //if (ring_avail < s->blocksize) {
     429  uint_t available = 0;
     430  if (ring_avail < (sint_t)s->blocksize) {
     431    available = aubio_sampler_pull_from_source(s);
     432    if (available > 0) {
     433      aubio_ringbuffer_push(s->ring, s->source_output, available);
     434    }
     435    if (available < s->source_blocksize) {
     436      if (ring_avail + available <= s->blocksize) {
     437        s->eof_remaining = available + ring_avail;
     438        if (s->eof_remaining == 0) s->eof_remaining = s->blocksize;
     439        //AUBIO_ERR("sampler: marking special eof got: %d, in ring: %d, %d, eof remaining %d\n",
     440        //    available, ring_avail, s->blocksize, s->eof_remaining);
     441        if (s->loop) {
     442          aubio_sampler_seek(s,0);
     443          // read some frames from beginning of source for perfect looping
     444          if (s->perfectloop) {
     445            available = aubio_sampler_pull_from_source(s);
     446            if (available <= 0) {
     447              AUBIO_ERR("sampler: perfectloop but s->available = 0 !\n");
     448            } else {
     449              aubio_ringbuffer_push(s->ring, s->source_output, available);
     450            }
     451          }
     452        }
     453      }
     454    }
     455  }
     456  return available;
     457}
     458
     459static void
     460aubio_sampler_reading_from_source_ring_pull(aubio_sampler_t *s, fvec_t *output,
     461    uint_t *read)
     462{
     463  // write into output
     464  int ring_avail = aubio_ringbuffer_get_available(s->ring);
     465  if (ring_avail >= (sint_t)s->blocksize) {
     466    //AUBIO_MSG("sampler: pulling %d / %d from ringbuffer\n", s->blocksize, ring_avail);
     467    aubio_ringbuffer_pull(s->ring, output, s->blocksize);
     468    *read = s->blocksize;
     469    if (s->eof_remaining > 0) {
     470      if (s->eof_remaining <= s->blocksize) {
     471        //AUBIO_WRN("sampler: signaling eof\n");
     472        s->eof = 1; // signal eof
     473        s->eof_remaining = 0;
     474      } else if (s->eof_remaining <= s->source_blocksize) {
     475        s->eof_remaining -= s->blocksize;
     476      }
     477    }
     478  } else {
     479    //AUBIO_MSG("sampler: last frame, pulling remaining %d left\n", ring_avail);
     480    *read = 0;
     481    if (ring_avail > 0) {
     482      // pull remaining frames in ring buffer
     483      aubio_ringbuffer_pull(s->ring, output, ring_avail);
     484      *read += ring_avail;
     485    }
     486    // signal eof
     487    aubio_sampler_do_eof(s);
     488    // finished playing, reset ringbuffer for next read
     489    if (!s->playing)
     490      aubio_ringbuffer_reset(s->ring);
     491  }
     492}
     493
     494static void
     495aubio_sampler_reading_from_source_ring(aubio_sampler_t *s, fvec_t *output,
     496    uint_t *read)
     497{
     498  aubio_sampler_reading_from_source_ring_fetch(s);
     499  aubio_sampler_reading_from_source_ring_pull(s, output, read);
     500}
     501
     502#ifdef HAVE_THREADS
     503static void
     504aubio_sampler_read_from_source_threaded(aubio_sampler_t *s, fvec_t *output,
     505    uint_t *read) {
     506  // request at least output->length
     507  // make sure we have enough samples read from source
     508  int available;
     509  pthread_mutex_lock(&s->read_mutex);
     510  if (!s->opened || s->open_thread_running) {
     511    //AUBIO_ERR("sampler: _read_from_source: not opened, signaling read_request\n");
     512    pthread_cond_signal(&s->read_request);
     513    available = 0;
     514  } else if (!s->finished) {
     515    pthread_cond_signal(&s->read_request);
     516    pthread_cond_wait(&s->read_avail, &s->read_mutex);
     517    //AUBIO_ERR("sampler: _read_from_source: %d\n", s->available);
     518    available = s->available;
     519  } else {
     520    //AUBIO_WRN("sampler: _read_from_source: eof\n");
     521    pthread_cond_signal(&s->read_request);
     522    available = 0;
     523  }
     524  pthread_mutex_unlock(&s->read_mutex);
     525  //AUBIO_WRN("sampler: got %d available in _read_from_source\n", available);
     526  // read -> number of samples read
     527  if (!s->perfectloop && s->source_blocksize == s->blocksize) {
     528    if (available >= (sint_t)s->blocksize) {
     529      fvec_copy(s->source_output, output);
     530      *read = s->blocksize;
     531    } else if (available > 0) {
     532      fvec_copy(s->source_output, output);
     533      *read = available;
     534    } else {
     535      fvec_zeros(output);
     536      *read = 0;
     537    }
     538  } else {
     539    aubio_sampler_reading_from_source_ring_pull(s, output, read);
     540  }
     541}
     542#endif
     543
     544void
     545aubio_sampler_read_from_source(aubio_sampler_t *s, fvec_t *output, uint_t *read) {
     546#ifdef HAVE_THREADS
     547  if (s->threaded_read) { // if threaded
     548    aubio_sampler_read_from_source_threaded(s, output, read);
     549  } else
     550#endif
     551  {
     552    if (s->finished) {
     553      *read = 0;
     554    }
     555    else if (s->source_blocksize == s->blocksize && !s->perfectloop) {
     556      aubio_sampler_reading_from_source_naive(s, output, read);
     557    } else {
     558      aubio_sampler_reading_from_source_ring(s, output, read);
     559    }
     560#if 1
     561    if (s->loop && s->perfectloop && *read != s->blocksize) { // && s->started && !s->finished) {
     562      AUBIO_ERR("sampler: perfectloop but read only %d\n", *read);
     563    }
     564#endif
     565  }
     566}
     567
     568void
     569aubio_sampler_read_from_table(aubio_sampler_t *s, fvec_t *output, uint_t *read) {
     570  *read = 0;
     571  if (s->table == NULL) {
     572    AUBIO_WRN("sampler: _pull_from_table but table not set %d, %d\n",
     573        output->length, *read);
     574  } else if (s->playing) {
     575    uint_t available = s->table->length - s->table_index;
     576    fvec_t tmp;
     577    tmp.data = s->table->data + s->table_index;
     578    if (available < s->blocksize) {
     579      //AUBIO_WRN("sampler: _pull_from_table: table length %d, index: %d, read %d\n",
     580      //    s->table->length, s->table_index, *read);
     581      tmp.length = available;
     582      fvec_t tmpout; tmpout.data = output->data; tmpout.length = available;
     583      fvec_copy(&tmp, &tmpout);
     584      if (s->loop && s->perfectloop) {
     585        uint_t remaining = s->blocksize - available;
     586        tmpout.data = output->data + available; tmpout.length = remaining;
     587        tmp.data = s->table->data; tmp.length = remaining;
     588        fvec_copy(&tmp, &tmpout);
     589        s->table_index = remaining;
     590        *read = s->blocksize;
     591      } else {
     592        s->table_index = 0;
     593        *read = available;
     594      }
     595      aubio_sampler_do_eof(s);
     596    } else {
     597      tmp.length = s->blocksize;
     598      fvec_copy(&tmp, output);
     599      s->table_index += output->length;
     600      *read = s->blocksize;
     601    }
     602  }
     603}
     604
     605uint_t
     606aubio_sampler_set_table(aubio_sampler_t *s, fvec_t *samples) {
     607  if (!samples || !s) return AUBIO_FAIL;
     608  if (s->reading_from == aubio_sampler_reading_from_source) {
     609    //aubio_sampler_close_reading_thread(s);
     610  }
     611  s->table = samples;
     612  //AUBIO_INF("sampler: setting table (%d long)\n", s->table->length);
     613  s->table_index = 0;
     614  s->reading_from = aubio_sampler_reading_from_table;
     615  //s->threaded_read = 0;
     616  s->opened = 1;
     617  s->finished = 1;
     618  return AUBIO_OK;
     619}
     620
     621sint_t
     622aubio_sampler_pull_from_source(aubio_sampler_t *s)
     623{
     624  // pull source_blocksize samples from source, return available frames
     625  uint_t source_read = s->source_blocksize;
     626  if (s->source == NULL) {
     627    AUBIO_ERR("sampler: trying to fetch on NULL source\n");
     628    return -1;
     629  }
     630  aubio_source_do(s->source, s->source_output, &source_read);
     631  return source_read;
     632}
     633
     634
     635uint_t
     636aubio_sampler_get_samplerate (aubio_sampler_t *o)
     637{
     638  return o->samplerate;
     639}
     640
     641uint_t
     642aubio_sampler_get_opened (aubio_sampler_t *o)
     643{
     644  return o->opened; //== 1 ? AUBIO_OK : AUBIO_FAIL;
     645}
     646
     647uint_t
     648aubio_sampler_get_finished(aubio_sampler_t *o)
     649{
     650  return o->finished;
     651}
     652
     653uint_t
     654aubio_sampler_get_eof (aubio_sampler_t *o)
     655{
     656  return o->eof;
     657}
     658
     659uint_t
     660aubio_sampler_get_waited_opening (aubio_sampler_t *o, uint_t waited) {
     661#ifdef HAVE_THREADS
    74662  if (o->playing) {
    75     aubio_source_do (o->source, o->source_output, &read);
    76     for (i = 0; i < output->length; i++) {
    77       output->data[i] += o->source_output->data[i];
    78     }
    79     if (read < o->blocksize) o->playing = 0;
    80   }
    81   if (input && input != output) {
    82     for (i = 0; i < output->length; i++) {
    83       output->data[i] += input->data[i];
    84     }
    85   }
    86 }
    87 
    88 void aubio_sampler_do_multi ( aubio_sampler_t * o, const fmat_t * input, fmat_t * output)
    89 {
    90   uint_t read = 0, i, j;
    91   if (o->playing) {
    92     aubio_source_do_multi (o->source, o->source_output_multi, &read);
    93     for (i = 0; i < output->height; i++) {
    94       for (j = 0; j < output->length; j++) {
    95         output->data[i][j] += o->source_output_multi->data[i][j];
    96       }
    97     }
    98     if ( read < o->blocksize ) o->playing = 0;
    99   }
    100   if (input && input != output) {
    101     for (i = 0; i < output->height; i++) {
    102       for (j = 0; j < output->length; j++) {
    103         output->data[i][j] += input->data[i][j];
    104       }
    105     }
     663    if (!o->opened) {
     664      o->waited += waited;
     665    } else if (o->waited) {
     666      //AUBIO_WRN("sampler: waited %d frames (%.2fms) while opening %s\n",
     667      //    o->waited, 1000.*o->waited/(smpl_t)o->samplerate, o->uri);
     668      uint_t waited = o->waited;
     669      o->waited = 0;
     670      return waited;
     671    }
     672  }
     673#endif
     674  return 0;
     675}
     676
     677uint_t
     678aubio_sampler_seek(aubio_sampler_t * o, uint_t pos)
     679{
     680  //AUBIO_WRN("sampler: seeking to 0\n");
     681  uint_t ret = AUBIO_FAIL;
     682  o->finished = 0;
     683  if (!o->opened) return AUBIO_OK;
     684  if (o->source) {
     685    ret = aubio_source_seek(o->source, pos);
     686  } else if (o->table && (sint_t)pos >= 0 && pos < o->table->length) {
     687    o->table_index = pos < o->table->length ? pos : o->table->length - 1;
     688    ret = AUBIO_OK;
     689  }
     690  return ret;
     691}
     692
     693void
     694aubio_sampler_do_eof (aubio_sampler_t * o)
     695{
     696  //AUBIO_MSG("sampler: calling  _do_eof()\n");
     697  o->finished = 1;
     698  o->eof = 1;
     699  if (!o->loop) {
     700    o->playing = 0;
     701  } else {
     702    if (o->reading_from == aubio_sampler_reading_from_source)
     703      aubio_sampler_seek(o, 0);
     704    //o->finished = 0;
     705  }
     706}
     707
     708void aubio_sampler_do ( aubio_sampler_t * o, fvec_t * output, uint_t *read)
     709{
     710  o->eof = 0;
     711  if (o->opened == 1 && o->playing) {
     712    aubio_sampler_read(o, output, read);
     713  } else {
     714    fvec_zeros(output);
     715    *read = 0;
     716  }
     717}
     718
     719void aubio_sampler_do_multi ( aubio_sampler_t * o, fmat_t * output, uint_t *read)
     720{
     721  o->eof = 0;
     722  if (o->opened == 1 && o->playing) {
     723    //aubio_sampler_read_multi(o, output, read);
     724  } else {
     725    fmat_zeros(output);
     726    *read = 0;
    106727  }
    107728}
     
    118739}
    119740
     741uint_t aubio_sampler_get_loop ( aubio_sampler_t * o )
     742{
     743  return o->loop;
     744}
     745
     746uint_t aubio_sampler_set_loop ( aubio_sampler_t * o, uint_t loop )
     747{
     748  o->loop = (loop == 1) ? 1 : 0;
     749  return 0;
     750}
     751
    120752uint_t aubio_sampler_play ( aubio_sampler_t * o )
    121753{
    122   aubio_source_seek (o->source, 0);
    123754  return aubio_sampler_set_playing (o, 1);
    124755}
     
    129760}
    130761
     762uint_t aubio_sampler_loop ( aubio_sampler_t * o )
     763{
     764  aubio_sampler_set_loop(o, 1);
     765  aubio_sampler_seek(o, 0);
     766  return aubio_sampler_set_playing (o, 1);
     767}
     768
     769uint_t aubio_sampler_trigger ( aubio_sampler_t * o )
     770{
     771  if (o->ring) aubio_ringbuffer_reset(o->ring);
     772  aubio_sampler_set_loop(o, 0);
     773  aubio_sampler_seek(o, 0);
     774  return aubio_sampler_set_playing (o, 1);
     775}
     776
     777uint_t aubio_sampler_set_perfectloop (aubio_sampler_t *s, uint_t perfectloop) {
     778  if (!s) return AUBIO_FAIL;
     779  s->perfectloop = perfectloop;
     780  return AUBIO_OK;
     781}
     782
     783uint_t aubio_sampler_get_perfectloop (aubio_sampler_t *s) {
     784  if (!s) return AUBIO_FAIL;
     785  return s->perfectloop;
     786}
     787
    131788void del_aubio_sampler( aubio_sampler_t * o )
    132789{
     790#ifdef HAVE_THREADS
     791  // close opening thread
     792  aubio_sampler_close_opening_thread(o);
     793  // close reading thread
     794  aubio_sampler_close_reading_thread(o);
     795#endif
     796  //if (o->source_output) {
     797  if (o->source_output && (o->threaded_read || o->perfectloop)) {
     798    del_fvec(o->source_output);
     799  }
     800  if (o->source_moutput) {
     801    del_fmat(o->source_moutput);
     802  }
     803  if (o->ring) {
     804    del_aubio_ringbuffer(o->ring);
     805  }
    133806  if (o->source) {
    134807    del_aubio_source(o->source);
    135808  }
    136   if (o->uri) AUBIO_FREE(o->uri);
    137   del_fvec(o->source_output);
    138   del_fmat(o->source_output_multi);
    139809  AUBIO_FREE(o);
    140810}
  • src/synth/sampler.h

    r67b6618 r41b985f  
    2424/** \file
    2525
    26   Load and play sound files.
     26  Load and play a sound file.
    2727
    2828  This file loads a sample and gets ready to play it.
     
    3030  The `_do` function adds the new samples to the input, and write the result as
    3131  the output.
     32
     33TODO:
     34  - add _preset_threaded(level)
     35  - add _set_stretch
     36  - add _set_pitch
    3237
    3338  \example synth/test-sampler.c
     
    5055
    5156*/
    52 aubio_sampler_t * new_aubio_sampler(uint_t samplerate, uint_t hop_size);
     57aubio_sampler_t * new_aubio_sampler(uint_t hop_size, uint_t samplerate);
    5358
    5459/** load source in sampler
     
    5964  \return 0 if successful, non-zero otherwise
    6065
     66  This function attempts to load a new source, swaps the current one with the
     67  newly loaded one (or NULL if loading failed), then delete the old one.
     68
    6169*/
    6270uint_t aubio_sampler_load( aubio_sampler_t * o, const char_t * uri );
    6371
     72/** queue source in sampler
     73
     74  \param o sampler, created by new_aubio_sampler()
     75  \param uri the uri of the source to load
     76
     77  \return 0 if successfully queued, non-zero otherwise
     78
     79  This function is identical to aubio_sampler_load(), except it will be called
     80  in its own thread to avoid blocking calls to aubio_sampler_do().
     81
     82*/
     83uint_t aubio_sampler_queue(aubio_sampler_t * o, const char_t * uri );
     84
     85/** set array to read from
     86
     87  \param o sampler, created by new_aubio_sampler()
     88  \param samples the vector to set the table to
     89
     90  \return 0 if successfully set, non-zero otherwise
     91
     92*/
     93uint_t aubio_sampler_set_table(aubio_sampler_t *o, fvec_t *samples);
     94
    6495/** process sampler function
    6596
    6697  \param o sampler, created by new_aubio_sampler()
    67   \param input input of the sampler, to be added to the output
    6898  \param output output of the sampler
    69 
    70 This function adds the new samples from the playing source to the output.
    71 
    72 If `input` is not NULL and different from `output`, then the samples from `input`
    73 are added to the output.
    74 
    75 */
    76 void aubio_sampler_do ( aubio_sampler_t * o, const fvec_t * input, fvec_t * output);
     99  \param read number of samples actually read
     100
     101  This function get new samples from the sampler and store them into output.
     102
     103  The output vector will be completed with 0 if too few samples are available.
     104
     105*/
     106void aubio_sampler_do ( aubio_sampler_t * o, fvec_t * output, uint_t *read);
    77107
    78108/** process sampler function, multiple channels
    79109
    80110  \param o sampler, created by new_aubio_sampler()
    81   \param input input of the sampler, to be added to the output
    82111  \param output output of the sampler
    83112
    84 This function adds the new samples from the playing source to the output.
    85 
    86 If `input` is not NULL and different from `output`, then the samples from `input`
    87 are added to the output.
    88 
    89 */
    90 void aubio_sampler_do_multi ( aubio_sampler_t * o, const fmat_t * input, fmat_t * output);
     113  This function is indentical to aubio_sampler_do(), but for a multi-channel source.
     114
     115*/
     116void aubio_sampler_do_multi ( aubio_sampler_t * o, fmat_t * output, uint_t *read);
    91117
    92118/** get current playing state
     
    109135uint_t aubio_sampler_set_playing ( aubio_sampler_t * o, uint_t playing );
    110136
     137uint_t aubio_sampler_get_loop(aubio_sampler_t * o);
     138
     139/** set current looping state
     140
     141  \param o sampler, created by new_aubio_sampler()
     142  \param looping 0 for not looping, 1 for looping
     143
     144  \return 0 if successful, 1 otherwise
     145
     146*/
     147uint_t aubio_sampler_set_loop(aubio_sampler_t * o, uint_t loop);
     148
    111149/** play sample from start
    112150
     
    118156uint_t aubio_sampler_play ( aubio_sampler_t * o );
    119157
     158/** play sample from start, looping it
     159
     160  \param o sampler, created by new_aubio_sampler()
     161
     162  \return 0 if successful, 1 otherwise
     163
     164*/
     165uint_t aubio_sampler_loop ( aubio_sampler_t * o );
     166
     167/** play sample from start, once
     168
     169  \param o sampler, created by new_aubio_sampler()
     170
     171  \return 0 if successful, 1 otherwise
     172
     173*/
     174uint_t aubio_sampler_trigger ( aubio_sampler_t * o );
     175
    120176/** stop sample
    121177
     
    126182*/
    127183uint_t aubio_sampler_stop ( aubio_sampler_t * o );
     184
     185/** get end-of-file status
     186
     187  \param o sampler, created by new_aubio_sampler()
     188
     189  \return 1 when the eof is being reached, 0 otherwise
     190
     191*/
     192uint_t aubio_sampler_get_eof(aubio_sampler_t * o);
     193
     194/** get end-of-file status
     195
     196  \param o sampler, created by new_aubio_sampler()
     197
     198  \return 1 when the eof is being reached, 0 otherwise
     199
     200*/
     201uint_t aubio_sampler_get_finished (aubio_sampler_t * o);
     202
     203/** get samplerate
     204
     205  \param o sampler, created by new_aubio_sampler()
     206
     207  \return samplerate of the sampler
     208
     209*/
     210uint_t aubio_sampler_get_samplerate(aubio_sampler_t * o);
     211
     212/** get the number of samples that were set to zero while opening a file
     213
     214  \param o sampler, created by new_aubio_sampler()
     215  \param waited the number of frames processed during this block
     216
     217  \return the total delay in samples when the file was successfuly opened, 0
     218  otherwise
     219
     220*/
     221uint_t aubio_sampler_get_waited_opening(aubio_sampler_t * o, uint_t waited);
     222
     223/** get the current perfect loop mode
     224
     225  \param o sampler, created by new_aubio_sampler()
     226
     227  \return the total delay in samples when the file was successfuly opened, 0
     228  otherwise
     229
     230*/
     231uint_t aubio_sampler_get_perfectloop (aubio_sampler_t *o);
     232
     233/** set the perfect loop mode
     234
     235  \param o sampler, created by new_aubio_sampler()
     236  \param perfectloop 1 to set perfect loop mode, 0 to turn it of
     237
     238  \return AUBIO_OK on success, AUBIO_FAIL otherwise
     239
     240 */
     241uint_t aubio_sampler_set_perfectloop (aubio_sampler_t *o, uint_t perfectloop);
     242
     243/** seek to position
     244
     245  \param o sampler, created by new_aubio_sampler()
     246  \param pos position to seek to, in samples
     247
     248  \return 0 if successful, 1 otherwise
     249
     250*/
     251uint_t aubio_sampler_seek(aubio_sampler_t * o, uint_t pos);
    128252
    129253/** destroy ::aubio_sampler_t object
  • src/wscript_build

    r67b6618 r41b985f  
    66uselib += ['SAMPLERATE']
    77uselib += ['SNDFILE']
     8uselib += ['RUBBERBAND']
    89uselib += ['AVCODEC']
    910uselib += ['AVFORMAT']
     
    1112uselib += ['AVUTIL']
    1213uselib += ['BLAS']
     14uselib += ['PTHREAD']
    1315
    1416source = ctx.path.ant_glob('*.c **/*.c')
  • tests/src/synth/test-sampler.c

    r67b6618 r41b985f  
    11#include <aubio.h>
    22#include "utils_tests.h"
     3
     4int time_was_reached (smpl_t time_s, uint_t n_frames, uint_t hop_size, uint_t samplerate) {
     5    if ((n_frames / hop_size) == (uint_t)(time_s * samplerate) / hop_size) {
     6      PRINT_MSG("reached %.2f sec at %d samples\n", time_s, n_frames);
     7      return 1;
     8    } else {
     9      return 0;
     10    }
     11}
    312
    413int main (int argc, char **argv)
     
    615  sint_t err = 0;
    716
    8   if (argc < 4) {
     17  if (argc < 2) {
    918    err = 2;
    1019    PRINT_ERR("not enough arguments\n");
    11     PRINT_MSG("usage: %s <input_path> <output_path> <sample_path> [samplerate]\n", argv[0]);
     20    PRINT_MSG("usage: %s <sample_path> [samplerate] [blocksize] [output_path]\n", argv[0]);
    1221    return err;
    1322  }
    1423
    15   uint_t samplerate = 0; // default is the samplerate of input_path
    16   uint_t hop_size = 256;
    17   uint_t n_frames = 0, read = 0;
     24  uint_t samplerate = 44100; // default is 44100
     25  uint_t hop_size = 64; //256;
     26  uint_t n_frames = 0, frames_played = 0;
     27  uint_t read = 0;
     28  char_t *sink_path = NULL;
     29  aubio_sink_t *sink = NULL;
    1830
    19   char_t *source_path = argv[1];
    20   char_t *sink_path = argv[2];
    21   char_t *sample_path = argv[3];
    22   if ( argc == 5 ) samplerate = atoi(argv[4]);
     31  char_t *sample_path = argv[1];
     32  if ( argc > 2 ) samplerate = atoi(argv[2]);
     33  if ( argc > 3 ) hop_size = atoi(argv[3]);
     34  if ( argc > 4 ) sink_path = argv[4];
    2335
    2436  fvec_t *vec = new_fvec(hop_size);
    25   aubio_source_t *source = new_aubio_source(source_path, samplerate, hop_size);
    26   if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(source);
    27   aubio_sink_t *sink = new_aubio_sink(sink_path, samplerate);
    2837
    29   aubio_sampler_t * sampler = new_aubio_sampler (samplerate, hop_size);
     38  aubio_sampler_t * sampler = new_aubio_sampler (hop_size, samplerate);
     39  if (!vec) goto beach;
     40  if (!sampler) goto beach_sampler;
     41  // load source file
     42  aubio_sampler_load (sampler, sample_path);
     43  // load source file (asynchronously)
     44  //aubio_sampler_queue (sampler, sample_path);
     45  samplerate = aubio_sampler_get_samplerate (sampler);
     46  if (samplerate == 0) {
     47    PRINT_ERR("starting with samplerate = 0\n");
     48    //goto beach_sink;
     49  }
    3050
    31   aubio_sampler_load (sampler, sample_path);
     51  if (sink_path) {
     52    sink = new_aubio_sink(sink_path, samplerate);
     53    if (!sink) goto beach_sink;
     54  }
     55
     56  smpl_t sample_duration = 2.953;
     57  uint_t sample_repeat = 10;
     58  smpl_t t1 = 1.,
     59         t2 = t1 + sample_duration * sample_repeat - .1,
     60         t3 = t2 - sample_duration + .1,
     61         t4 = t3 + sample_duration + .1,
     62         t5 = t4 + sample_duration + .1,
     63         total_duration = t5 + sample_duration + .1;
     64
     65  //aubio_sampler_set_transpose(sampler, 0.);
     66  //aubio_sampler_set_stretch(sampler, .8);
    3267
    3368  do {
    34     aubio_source_do(source, vec, &read);
    35     if (n_frames / hop_size == 10) {
     69    if (time_was_reached(t1, n_frames, hop_size, samplerate)) {
     70      PRINT_MSG("`-test one shot play of loaded sample\n");
     71      aubio_sampler_set_loop( sampler, 1);
    3672      aubio_sampler_play ( sampler );
     73    } else if (time_was_reached(t2, n_frames, hop_size, samplerate)) {
     74      PRINT_MSG("`-test queueing while playing after eof was reached\n");
     75      //aubio_sampler_queue (sampler, sample_path);
     76      //aubio_sampler_play (sampler);
     77      aubio_sampler_set_loop( sampler, 0);
     78#if 0
     79    } else if (time_was_reached(t3, n_frames, hop_size, samplerate)) {
     80      PRINT_MSG("`-test queueing twice cancels the first one\n");
     81      aubio_sampler_queue (sampler, sample_path);
     82      aubio_sampler_queue (sampler, sample_path);
     83      aubio_sampler_play (sampler);
     84    } else if (time_was_reached(t4, n_frames, hop_size, samplerate)) {
     85      PRINT_MSG("`-test queueing a corrupt file\n");
     86      aubio_sampler_queue (sampler, "/dev/null");
     87      aubio_sampler_play (sampler);
     88    } else if (time_was_reached(t5, n_frames, hop_size, samplerate)) {
     89      aubio_sampler_stop ( sampler );
     90      PRINT_MSG("`-test queueing a correct file after a corrupt one\n");
     91      uint_t i;
     92      for (i = 0; i < 4; i++)
     93        aubio_sampler_queue (sampler, "/dev/null");
     94      aubio_sampler_queue (sampler, "/dev/null1");
     95      aubio_sampler_queue (sampler, "/dev/null2");
     96      aubio_sampler_queue (sampler, sample_path);
     97      aubio_sampler_play (sampler);
     98#endif
    3799    }
     100    /*
    38101    if (n_frames / hop_size == 40) {
    39       aubio_sampler_play ( sampler );
     102      aubio_sampler_queue (sampler, sample_path);
     103      aubio_sampler_queue (sampler, sample_path);
     104      aubio_sampler_seek ( sampler, 0);
    40105    }
    41106    if (n_frames / hop_size == 70) {
    42       aubio_sampler_play ( sampler );
     107      aubio_sampler_seek ( sampler, 0);
    43108    }
    44     if (n_frames > 10.0 * samplerate) {
    45       aubio_sampler_stop ( sampler );
    46     }
    47     aubio_sampler_do (sampler, vec, vec);
    48     aubio_sink_do(sink, vec, read);
    49     n_frames += read;
    50   } while ( read == hop_size );
     109    */
     110    aubio_sampler_do (sampler, vec, &read);
     111    if (sink) aubio_sink_do(sink, vec, hop_size);
     112    n_frames += hop_size;
     113    frames_played += read;
     114  //} while ( read == hop_size );
     115    // last for 40 seconds
     116  } while ( n_frames <= total_duration * samplerate );
     117  PRINT_MSG("reached %.2f sec at %d samples, sampler played %d frames\n",
     118      total_duration, n_frames, frames_played);
    51119
     120  if (sink) del_aubio_sink(sink);
     121beach_sink:
    52122  del_aubio_sampler(sampler);
    53   del_aubio_source(source);
    54   del_aubio_sink(sink);
     123beach_sampler:
    55124  del_fvec(vec);
     125beach:
    56126  aubio_cleanup();
    57 
    58127  return 0;
    59128}
  • wscript

    r67b6618 r41b985f  
    7575            help_str = 'compile with samplerate (auto)',
    7676            help_disable_str = 'disable samplerate')
     77    add_option_enable_disable(ctx, 'rubberband', default = None,
     78            help_str = 'compile with rubberband (auto)',
     79            help_disable_str = 'disable rubberband')
    7780    add_option_enable_disable(ctx, 'memcpy', default = True,
    7881            help_str = 'use memcpy hacks (default)',
     
    127130    ctx.check(header_name='unistd.h', mandatory = False)
    128131
     132    ctx.check(header_name='pthread.h', mandatory = False)
     133    needs_pthread = ctx.get_define("HAVE_PTHREAD_H") is not None
     134    if needs_pthread:
     135        ctx.check_cc(lib="pthread", uselib_store="PTHREAD", mandatory=needs_pthread)
     136
    129137    target_platform = sys.platform
    130138    if ctx.options.target_platform:
     
    307315                args = '--cflags --libs',
    308316                mandatory = ctx.options.enable_samplerate)
     317
     318    # check for librubberband
     319    if (ctx.options.enable_rubberband != False):
     320        ctx.check_cfg(package = 'rubberband', atleast_version = '1.3',
     321                args = '--cflags --libs',
     322                mandatory = ctx.options.enable_rubberband)
    309323
    310324    # check for jack
Note: See TracChangeset for help on using the changeset viewer.