Changeset 0202028


Ignore:
Timestamp:
Sep 30, 2016, 1:54:50 AM (8 years ago)
Author:
Paul Brossier <piem@piem.org>
Branches:
sampler
Children:
b21c751
Parents:
4acee97
Message:

src/effects/timestretch_rubberband.c: add initial pthread support

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/effects/timestretch_rubberband.c

    r4acee97 r0202028  
    3434#define MAX_STRETCH_RATIO 40.
    3535
     36#define HAVE_THREADS 1
     37#if 0
     38#undef HAVE_THREADS
     39#endif
     40
     41#ifdef HAVE_THREADS
     42#include <pthread.h>
     43#endif
     44
    3645/** generic time stretching structure */
    3746struct _aubio_timestretch_t
     
    4958  RubberBandState rb;
    5059  RubberBandOptions rboptions;
     60
     61#ifdef HAVE_THREADS
     62  pthread_t read_thread;
     63  pthread_mutex_t read_mutex;
     64  pthread_cond_t read_avail;
     65  pthread_cond_t read_request;
     66  sint_t available;
     67#endif
    5168};
    5269
     
    5572static void aubio_timestretch_warmup (aubio_timestretch_t * p);
    5673static sint_t aubio_timestretch_fetch(aubio_timestretch_t *p, uint_t fetch);
     74#ifdef HAVE_THREADS
     75static void *aubio_timestretch_readfn(void *p);
     76#endif
    5777
    5878aubio_timestretch_t *
     
    6383  p->samplerate = samplerate;
    6484  p->hopsize = hopsize;
     85  //p->source_hopsize = 2048;
    6586  p->source_hopsize = hopsize;
    6687  p->pitchscale = 1.;
     
    91112  //rubberband_set_debug_level(p->rb, 10);
    92113
     114#ifdef HAVE_THREADS
     115  pthread_mutex_init(&p->read_mutex, 0);
     116  pthread_cond_init (&p->read_avail, 0);
     117  pthread_cond_init (&p->read_request, 0);
     118  pthread_create(&p->read_thread, 0, aubio_timestretch_readfn, p);
     119  //AUBIO_DBG("timestretch: new_ waiting for warmup, got %d available\n", p->available);
     120  pthread_mutex_lock(&p->read_mutex);
     121  pthread_cond_wait(&p->read_avail, &p->read_mutex);
     122  pthread_mutex_unlock(&p->read_mutex);
     123  //AUBIO_DBG("timestretch: new_ warm up success, got %d available\n", p->available);
     124#else
    93125  aubio_timestretch_warmup(p);
     126#endif
    94127
    95128  return p;
     
    100133}
    101134
     135#ifdef HAVE_THREADS
     136void *
     137aubio_timestretch_readfn(void *z)
     138{
     139  aubio_timestretch_t *p = z;
     140  // signal main-thread when we are done
     141  //AUBIO_WRN("timestretch: read_thread locking, got %d available\n", p->available);
     142  pthread_mutex_lock(&p->read_mutex);
     143  aubio_timestretch_warmup(p);
     144  //AUBIO_WRN("timestretch: signaling warmup\n");
     145  pthread_cond_signal(&p->read_avail);
     146  //AUBIO_WRN("timestretch: unlocking in readfn\n");
     147  pthread_mutex_unlock(&p->read_mutex);
     148  AUBIO_WRN("timestretch: entering readfn loop\n");
     149  while(1) { //p->available < (int)p->hopsize && p->eof != 1) {
     150    //AUBIO_WRN("timestretch: locking in readfn\n");
     151    pthread_mutex_lock(&p->read_mutex);
     152    p->available = aubio_timestretch_fetch(p, p->hopsize);
     153    //AUBIO_WRN("timestretch: read_thread read %d\n", p->available);
     154    // signal main-thread when we are done
     155    //AUBIO_WRN("timestretch: signaling new read\n");
     156    pthread_cond_signal(&p->read_avail);
     157    if (p->eof != 1) {
     158      pthread_cond_wait(&p->read_request, &p->read_mutex);
     159    }
     160    if (p->eof == 1) {
     161      AUBIO_WRN("timestretch: read_thread eof reached %d, %d/%d\n", p->available,
     162        p->hopsize, p->source_hopsize);
     163      pthread_mutex_unlock(&p->read_mutex);
     164      break;
     165    }
     166    //AUBIO_WRN("timestretch: unlocking in readfn\n");
     167    pthread_mutex_unlock(&p->read_mutex);
     168  }
     169#if 1
     170  pthread_mutex_lock(&p->read_mutex);
     171  //AUBIO_WRN("timestretch: signaling end\n");
     172  pthread_cond_signal(&p->read_avail);
     173  pthread_mutex_unlock(&p->read_mutex);
     174#endif
     175  //AUBIO_WRN("timestretch: exiting readfn\n");
     176  pthread_exit(NULL);
     177}
     178#endif
     179
    102180static void
    103181aubio_timestretch_warmup (aubio_timestretch_t * p)
     
    105183  // warm up rubber band
    106184  unsigned int latency = MAX(p->hopsize, rubberband_get_latency(p->rb));
     185#ifdef HAVE_THREADS
     186  p->available = aubio_timestretch_fetch(p, latency);
     187#else
    107188  aubio_timestretch_fetch(p, latency);
     189#endif
    108190}
    109191
     
    111193del_aubio_timestretch (aubio_timestretch_t * p)
    112194{
     195#ifdef HAVE_THREADS
     196  pthread_mutex_lock(&p->read_mutex);
     197  pthread_cond_signal(&p->read_request);
     198  //pthread_cond_wait(&p->read_avail, &p->read_mutex);
     199  pthread_mutex_unlock(&p->read_mutex);
     200#if 1
     201  void *threadfn;
     202  if ((p->eof == 0) && (pthread_cancel(p->read_thread))) {
     203      AUBIO_WRN("timestretch: cancelling thread failed\n");
     204  }
     205  if (pthread_join(p->read_thread, &threadfn)) {
     206      AUBIO_WRN("timestretch: joining thread failed\n");
     207  }
     208#endif
     209  pthread_mutex_destroy(&p->read_mutex);
     210  pthread_cond_destroy(&p->read_avail);
     211  pthread_cond_destroy(&p->read_request);
     212#endif
    113213  if (p->in) del_fvec(p->in);
    114214  if (p->source) del_aubio_source(p->source);
     
    205305aubio_timestretch_do (aubio_timestretch_t * p, fvec_t * out, uint_t * read)
    206306{
     307#ifndef HAVE_THREADS
    207308  int available = aubio_timestretch_fetch(p, p->hopsize);
     309#else /* HAVE_THREADS */
     310  int available;
     311  pthread_mutex_lock(&p->read_mutex);
     312  if (p->eof != 1) {
     313    // signal a read request
     314    pthread_cond_signal(&p->read_request);
     315    // wait for an available signal
     316    pthread_cond_wait(&p->read_avail, &p->read_mutex);
     317  } else {
     318    available = rubberband_available(p->rb);
     319  }
     320#endif /* HAVE_THREADS */
    208321  // now retrieve the samples and write them into out->data
    209322  if (available >= (int)p->hopsize) {
     
    217330    *read = 0;
    218331  }
     332#ifdef HAVE_THREADS
     333  pthread_mutex_unlock(&p->read_mutex);
     334#endif
    219335}
    220336
     
    222338aubio_timestretch_seek (aubio_timestretch_t *p, uint_t pos)
    223339{
     340  uint_t err = AUBIO_OK;
     341#if HAVE_THREADS
     342  AUBIO_WRN("timestretch: seek_ waiting for warmup, got %d available\n", p->available);
     343  pthread_mutex_lock(&p->read_mutex);
     344#endif
    224345  p->eof = 0;
    225346  rubberband_reset(p->rb);
    226   return aubio_source_seek(p->source, pos);
    227 }
    228 
    229 #endif
     347  err = aubio_source_seek(p->source, pos);
     348#if HAVE_THREADS
     349  p->available = 0;
     350  void *threadfn;
     351  if ((p->eof == 0) && (pthread_cancel(p->read_thread) == 0)) {
     352      AUBIO_WRN("timestretch: cancelling thread failed\n");
     353  }
     354  if (pthread_join(p->read_thread, &threadfn)) {
     355      AUBIO_WRN("timestretch: joining thread failed\n");
     356  }
     357  pthread_create(&p->read_thread, 0, aubio_timestretch_readfn, p);
     358  pthread_cond_wait(&p->read_avail, &p->read_mutex);
     359  pthread_mutex_unlock(&p->read_mutex);
     360  //AUBIO_WRN("timestretch: seek_ warm up success, got %d available\n", p->available);
     361#endif
     362  return err;
     363}
     364
     365#endif
Note: See TracChangeset for help on using the changeset viewer.