From 2ca4b59b6670a55a13bcc81b5cc408d98d9fe520 Mon Sep 17 00:00:00 2001 From: Paul Brossier Date: Tue, 11 Oct 2016 02:37:25 +0200 Subject: [PATCH] src/synth/sampler.c: add _set_table and allow switching to/from table or source --- src/synth/sampler.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++----- src/synth/sampler.h | 10 +++++++ 2 files changed, 84 insertions(+), 7 deletions(-) diff --git a/src/synth/sampler.c b/src/synth/sampler.c index 7c638db7..5e3ad3cc 100644 --- a/src/synth/sampler.c +++ b/src/synth/sampler.c @@ -59,12 +59,12 @@ struct _aubio_sampler_t { uint_t reading_from; // current interpolation mode (can be quadratic, timestretch, ...) uint_t interp; - // reading from a table aubio_ringbuffer_t *ring; uint_t perfectloop; uint_t eof_remaining; - fvec_t *samples; - fmat_t *msamples; + // reading from a table + fvec_t *table; + uint_t table_index; // reading from a source aubio_source_t *source; const char_t *uri; @@ -170,6 +170,15 @@ aubio_sampler_t *new_aubio_sampler(uint_t blocksize, uint_t samplerate) } #endif +#if 0 + s->reading_from = aubio_sampler_reading_from_table; + s->perfectloop = 1; + s->threaded_read = 0; + s->opened = 1; + s->finished = 1; + s->table_index = 0; +#endif + return s; beach: AUBIO_FREE(s); @@ -195,6 +204,7 @@ void aubio_sampler_open_reading_thread(aubio_sampler_t *s) { void aubio_sampler_close_opening_thread(aubio_sampler_t *o) { // clean up opening thread void *threadret; + if (!o->open_thread) return; pthread_mutex_destroy(&o->open_mutex); if (o->open_thread_running) { if (pthread_cancel(o->open_thread)) { @@ -205,6 +215,7 @@ void aubio_sampler_close_opening_thread(aubio_sampler_t *o) { AUBIO_WRN("sampler: joining file opening thread failed\n"); } pthread_mutex_destroy(&o->open_mutex); + o->open_thread = 0; } void aubio_sampler_close_reading_thread(aubio_sampler_t *o) { @@ -222,6 +233,7 @@ void aubio_sampler_close_reading_thread(aubio_sampler_t *o) { pthread_mutex_destroy(&o->read_mutex); pthread_cond_destroy(&o->read_avail); pthread_cond_destroy(&o->read_request); + o->read_thread = 0; } #endif @@ -292,6 +304,12 @@ aubio_sampler_queue(aubio_sampler_t *o, const char_t *uri) { #ifdef HAVE_THREADS uint_t ret = AUBIO_OK; + + if (o->reading_from == aubio_sampler_reading_from_table) { + o->reading_from = aubio_sampler_reading_from_source; + o->opened = 0; + o->finished = 1; + } /* open uri in open_thread */ if (o->open_thread_running) { // cancel previous open_thread @@ -548,10 +566,56 @@ aubio_sampler_read_from_source(aubio_sampler_t *s, fvec_t *output, uint_t *read) } void -aubio_sampler_read_from_table(aubio_sampler_t *o, fvec_t *output, uint_t *read) { +aubio_sampler_read_from_table(aubio_sampler_t *s, fvec_t *output, uint_t *read) { *read = 0; - AUBIO_WRN("sampler: _pull_from_table not implemented for %d, %d, %d", - o, output->length, *read); + if (s->table == NULL) { + AUBIO_WRN("sampler: _pull_from_table but table not set %d, %d\n", + output->length, *read); + } else if (s->playing) { + uint_t available = s->table->length - s->table_index; + fvec_t tmp; + tmp.data = s->table->data + s->table_index; + if (available < s->blocksize) { + //AUBIO_WRN("sampler: _pull_from_table: table length %d, index: %d, read %d\n", + // s->table->length, s->table_index, *read); + tmp.length = available; + fvec_t tmpout; tmpout.data = output->data; tmpout.length = available; + fvec_copy(&tmp, &tmpout); + if (s->loop && s->perfectloop) { + uint_t remaining = s->blocksize - available; + tmpout.data = output->data + available; tmpout.length = remaining; + tmp.data = s->table->data; tmp.length = remaining; + fvec_copy(&tmp, &tmpout); + s->table_index = remaining; + *read = s->blocksize; + } else { + s->table_index = 0; + *read = available; + } + aubio_sampler_do_eof(s); + } else { + tmp.length = s->blocksize; + fvec_copy(&tmp, output); + s->table_index += output->length; + *read = s->blocksize; + } + } +} + +uint_t +aubio_sampler_set_table(aubio_sampler_t *s, fvec_t *samples) { + if (!samples || !s) return AUBIO_FAIL; + if (s->reading_from == aubio_sampler_reading_from_source) { + //aubio_sampler_close_reading_thread(s); + } + s->table = samples; + //AUBIO_INF("sampler: setting table (%d long)\n", s->table->length); + s->table_index = 0; + s->reading_from = aubio_sampler_reading_from_table; + //s->threaded_read = 0; + s->opened = 1; + s->finished = 1; + return AUBIO_OK; } sint_t @@ -619,6 +683,8 @@ aubio_sampler_seek(aubio_sampler_t * o, uint_t pos) if (!o->opened) return AUBIO_OK; if (o->source) { ret = aubio_source_seek(o->source, pos); + } else { + o->table_index = pos; } return ret; } @@ -632,7 +698,8 @@ aubio_sampler_do_eof (aubio_sampler_t * o) if (!o->loop) { o->playing = 0; } else { - aubio_sampler_seek(o, 0); + if (o->reading_from == aubio_sampler_reading_from_source) + aubio_sampler_seek(o, 0); //o->finished = 0; } } diff --git a/src/synth/sampler.h b/src/synth/sampler.h index 1cd0b729..3b32bc12 100644 --- a/src/synth/sampler.h +++ b/src/synth/sampler.h @@ -82,6 +82,16 @@ uint_t aubio_sampler_load( aubio_sampler_t * o, const char_t * uri ); */ uint_t aubio_sampler_queue(aubio_sampler_t * o, const char_t * uri ); +/** set array to read from + + \param o sampler, created by new_aubio_sampler() + \param samples the vector to set the table to + + \return 0 if successfully set, non-zero otherwise + +*/ +uint_t aubio_sampler_set_table(aubio_sampler_t *o, fvec_t *samples); + /** process sampler function \param o sampler, created by new_aubio_sampler() -- 2.11.0