Changeset 82ad1ed


Ignore:
Timestamp:
Mar 12, 2017, 2:45:16 PM (3 years ago)
Author:
Paul Brossier <piem@piem.org>
Branches:
sampler
Children:
75d1f9b
Parents:
8b07fa9
Message:

src/synth/sampler.h: add timestretch (first draft)

Location:
src/synth
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/synth/sampler.c

    r8b07fa9 r82ad1ed  
    2626#include "io/source.h"
    2727#include "utils/ringbuffer.h"
     28#include "effects/timestretch.h"
    2829#include "synth/sampler.h"
    2930
     
    7374  uint_t finished;              // end of file was reached
    7475  uint_t eof;                   // end of file is now
     76  // time stretching
     77  aubio_timestretch_t *ts;
    7578#ifdef HAVE_THREADS
    7679  // file reading thread
     
    179182#endif
    180183
     184  s->ts = new_aubio_timestretch("default", 1., s->blocksize, s->samplerate);
     185  s->source_output_tmp = new_fvec(s->source_blocksize);
     186  s->last_read = 0;
     187
    181188  return s;
    182189beach:
     
    259266    o->opened = 1;
    260267    ret = AUBIO_OK;
    261     AUBIO_WRN("sampler: loaded %s\n", uri);
     268    AUBIO_MSG("sampler: loaded %s\n", uri);
    262269    if (o->waited) {
    263270      AUBIO_WRN("sampler: %.2fms (%d samples) taken to load %s\n", 1000. *
     
    433440      aubio_ringbuffer_push(s->ring, s->source_output, available);
    434441    }
    435     if (available < s->source_blocksize) {
     442    if (available < s->blocksize) {
     443      //AUBIO_WRN("sampler: short read %d\n", available);
    436444      if (ring_avail + available <= s->blocksize) {
    437445        s->eof_remaining = available + ring_avail;
    438446        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);
     447        ring_avail = aubio_ringbuffer_get_available(s->ring);
     448        //AUBIO_ERR("sampler: eof in: %d, last fetch: %d, in ring: %d\n",
     449        //    s->eof_remaining, available, ring_avail);
    441450        if (s->loop) {
    442451          aubio_sampler_seek(s,0);
     
    496505    uint_t *read)
    497506{
     507#if 0
    498508  aubio_sampler_reading_from_source_ring_fetch(s);
    499509  aubio_sampler_reading_from_source_ring_pull(s, output, read);
     510#else // raw version
     511  uint_t source_read;
     512  while (aubio_timestretch_get_available(s->ts) < (sint_t)s->blocksize
     513      && s->eof_remaining == 0) {
     514    aubio_source_do(s->source, s->source_output, &source_read);
     515    aubio_timestretch_push(s->ts, s->source_output, source_read);
     516    if (source_read < s->source_output->length) s->eof_remaining = source_read;
     517    //AUBIO_WRN("sampler: pushed %d, now %d available\n",
     518    //    source_read, aubio_timestretch_get_available(s->ts));
     519  }
     520  aubio_timestretch_do(s->ts, output, read);
     521  if (s->eof_remaining > s->blocksize) {
     522    s->eof_remaining -= s->blocksize;
     523  }
     524  if (*read < output->length) {
     525    //AUBIO_WRN("sampler: short read %d, eof at %d\n", *read, s->eof_remaining);
     526    s->eof_remaining = 0;
     527    aubio_timestretch_reset(s->ts);
     528    aubio_sampler_do_eof(s);
     529    if (s->loop && s->perfectloop) {
     530      fvec_t tmpout; tmpout.data = output->data + *read;
     531      tmpout.length = output->length - *read;
     532      uint_t partialread;
     533      while (aubio_timestretch_get_available(s->ts) < (sint_t)tmpout.length
     534          && s->eof_remaining == 0) {
     535        aubio_source_do(s->source, s->source_output, &source_read);
     536        aubio_timestretch_push(s->ts, s->source_output, source_read);
     537        if (source_read < s->source_output->length) s->eof_remaining = source_read;
     538      }
     539      aubio_timestretch_do(s->ts, &tmpout, &partialread);
     540      //AUBIO_WRN("sampler: partial read %d + %d\n", *read, partialread);
     541      *read += partialread;
     542    }
     543  }
     544#endif
    500545}
    501546
     
    573618        output->length, *read);
    574619  } else if (s->playing) {
     620#if 0
    575621    uint_t available = s->table->length - s->table_index;
    576622    fvec_t tmp;
     
    600646      *read = s->blocksize;
    601647    }
     648#else
     649    fvec_t tmp, tmpout;
     650    uint_t source_read = 0;
     651    while (aubio_timestretch_get_available(s->ts) < (sint_t)s->blocksize
     652        && s->eof_remaining == 0) {
     653      uint_t available = s->table->length - s->table_index;
     654      if (available < s->source_blocksize) {
     655        source_read = available;
     656      } else {
     657        source_read = s->source_blocksize;
     658      }
     659      tmp.length = source_read; tmp.data = s->table->data + s->table_index;
     660      tmpout.data = s->source_output->data; tmpout.length = source_read;
     661      fvec_copy(&tmp, &tmpout);
     662      aubio_timestretch_push(s->ts, &tmpout, source_read);
     663      if (source_read < s->source_blocksize) {
     664        s->eof_remaining = source_read;
     665        s->table_index = s->source_blocksize - *read;
     666      } else {
     667        s->table_index += source_read;
     668      }
     669      if (s->table_index == s->table->length) s->table_index = 0;
     670      //AUBIO_WRN("sampler: pushed %d, now %d available, table_index %d, eof %d\n",
     671      //    source_read, aubio_timestretch_get_available(s->ts),
     672      //    s->table_index, s->eof_remaining);
     673    }
     674    aubio_timestretch_do(s->ts, output, read);
     675    if (*read == 0) {
     676      //AUBIO_WRN("sampler: pushed %d, now %d available, table_index %d\n",
     677      //    *read, aubio_timestretch_get_available(s->ts), s->table_index);
     678    }
     679    if (s->eof_remaining > s->blocksize) {
     680      s->eof_remaining -= s->blocksize;
     681    }
     682    if (*read < output->length) {
     683      s->eof_remaining = 0;
     684      aubio_sampler_do_eof(s);
     685    }
     686#if 0
     687    if (*read < output->length) {
     688      //uint_t available = aubio_timestretch_get_available(s->ts);
     689      s->eof_remaining = 0;
     690      aubio_timestretch_reset(s->ts);
     691      aubio_sampler_do_eof(s);
     692    }
     693#endif
     694#if 0
     695    if (*read < output->length) {
     696      //uint_t available = aubio_timestretch_get_available(s->ts);
     697      s->eof_remaining = 0;
     698      aubio_timestretch_reset(s->ts);
     699      aubio_sampler_do_eof(s);
     700      if (s->loop && s->perfectloop) {
     701        tmpout.data = output->data + *read;
     702        tmpout.length = output->length - *read;
     703        while (aubio_timestretch_get_available(s->ts) < (sint_t)tmpout.length
     704            && s->eof_remaining == 0) {
     705          uint_t available = s->table->length - s->table_index;
     706          if (available < s->source_blocksize) {
     707            source_read = available;
     708          } else {
     709            source_read = s->source_blocksize;
     710          }
     711          //AUBIO_WRN("sampler: short read %d, remaining %d\n", *read, remaining);
     712          tmp.length = source_read; tmp.data = s->table->data + s->table_index;
     713          fvec_t tmpout2; tmpout2.data = s->source_output->data; tmpout2.length = source_read;
     714          fvec_copy(&tmp, &tmpout2);
     715          aubio_timestretch_push(s->ts, &tmpout2, source_read);
     716          if (source_read < s->source_blocksize) {
     717            s->eof_remaining = source_read;
     718            s->table_index = 0;
     719          } else {
     720            s->table_index += source_read;
     721          }
     722          if (s->table_index == s->table->length) s->table_index = 0;
     723          //AUBIO_WRN("sampler: second push, pushed %d, now %d available\n",
     724          //    source_read, aubio_timestretch_get_available(s->ts));
     725        }
     726        uint_t partialread;
     727        aubio_timestretch_do(s->ts, &tmpout, &partialread);
     728        AUBIO_WRN("sampler: partial read %d + %d\n", *read, partialread);
     729        *read += partialread;
     730        //s->eof = 1;
     731      }
     732    }
     733#endif
     734
     735#endif
    602736  }
    603737}
     
    628762    return -1;
    629763  }
     764#if 1
    630765  aubio_source_do(s->source, s->source_output, &source_read);
    631766  return source_read;
     767#else
     768  uint_t source_read_tmp;
     769  while (aubio_timestretch_get_available(s->ts) < (sint_t)s->blocksize
     770      && s->last_read == 0) {
     771    aubio_source_do(s->source, s->source_output_tmp, &source_read_tmp);
     772    aubio_timestretch_push(s->ts, s->source_output_tmp, source_read_tmp);
     773    if (source_read_tmp < s->source_output_tmp->length) s->last_read = source_read;
     774  }
     775  aubio_timestretch_do(s->ts, s->source_output, &source_read);
     776  if (s->last_read > s->blocksize) {
     777    s->last_read -= s->blocksize;
     778  }
     779  if (source_read < s->source_blocksize) {
     780    s->last_read = 0;
     781    //AUBIO_ERR("sampler: calling timestretch reset %d %d\n", source_read, s->source_blocksize);
     782    aubio_timestretch_reset(s->ts);
     783  }
     784  return source_read;
     785#endif
    632786}
    633787
     
    688842    ret = AUBIO_OK;
    689843  }
     844  o->last_read = 0;
    690845  return ret;
    691846}
     
    786941}
    787942
     943
     944uint_t aubio_sampler_set_stretch(aubio_sampler_t *s, smpl_t stretch)
     945{
     946  if (!s->ts) return AUBIO_FAIL;
     947  return aubio_timestretch_set_stretch(s->ts, stretch);
     948}
     949
     950smpl_t aubio_sampler_get_stretch(aubio_sampler_t *s)
     951{
     952  if (!s->ts) return 1.;
     953  return aubio_timestretch_get_stretch(s->ts);
     954}
     955
     956uint_t aubio_sampler_set_transpose(aubio_sampler_t *s, smpl_t transpose)
     957{
     958  if (!s->ts) return AUBIO_FAIL;
     959  return aubio_timestretch_set_transpose(s->ts, transpose);
     960}
     961
     962smpl_t aubio_sampler_get_transpose(aubio_sampler_t *s)
     963{
     964  if (!s->ts) return 0.;
     965  return aubio_timestretch_get_transpose(s->ts);
     966}
     967
     968
    788969void del_aubio_sampler( aubio_sampler_t * o )
    789970{
     
    804985    del_aubio_ringbuffer(o->ring);
    805986  }
     987  if (o->ts) {
     988    del_aubio_timestretch(o->ts);
     989  }
    806990  if (o->source) {
    807991    del_aubio_source(o->source);
  • src/synth/sampler.h

    r8b07fa9 r82ad1ed  
    221221uint_t aubio_sampler_get_waited_opening(aubio_sampler_t * o, uint_t waited);
    222222
     223/** get current time stretching factor
     224
     225  \param o sampler, created by new_aubio_sampler()
     226
     227  \return the current time stretch factor
     228
     229 */
     230smpl_t aubio_sampler_get_stretch (aubio_sampler_t *o);
     231
     232/** set current time stretching factor
     233
     234  \param o sampler, created by new_aubio_sampler()
     235  \param stretch new time stretching factor
     236
     237  \return AUBIO_OK on success, AUBIO_FAIL otherwise
     238
     239 */
     240uint_t aubio_sampler_set_stretch (aubio_sampler_t *o, smpl_t stretch);
     241
     242/** get current pitch shifting factor
     243
     244  \param o sampler, created by new_aubio_sampler()
     245
     246  \return the current pitch transposition factor
     247
     248 */
     249smpl_t aubio_sampler_get_transpose (aubio_sampler_t *o);
     250
     251/** set current pitch shifting factor
     252
     253  \param o sampler, created by new_aubio_sampler()
     254  \param transpose new pitch shifting (transposition) factor
     255
     256  \return AUBIO_OK on success, AUBIO_FAIL otherwise
     257
     258 */
     259uint_t aubio_sampler_set_transpose (aubio_sampler_t *o, smpl_t transpose);
     260
    223261/** get the current perfect loop mode
    224262
Note: See TracChangeset for help on using the changeset viewer.