source: src/synth/sampler.c @ 41b985f

sampler
Last change on this file since 41b985f was 41b985f, checked in by Paul Brossier <piem@piem.org>, 7 years ago

Merge 'origin/master' into sampler

Conflicts:

.travis.yml
Makefile
examples/aubionotes.c
examples/parse_args.h
python/demos/demo_timestretch_online.py
python/lib/moresetuptools.py
python/tests/test_source.py
setup.py
src/io/source.c

  • Property mode set to 100644
File size: 22.6 KB
Line 
1/*
2  Copyright (C) 2003-2013 Paul Brossier <piem@aubio.org>
3
4  This file is part of aubio.
5
6  aubio is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10
11  aubio is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15
16  You should have received a copy of the GNU General Public License
17  along with aubio.  If not, see <http://www.gnu.org/licenses/>.
18
19*/
20
21#include <assert.h>
22
23#include "aubio_priv.h"
24#include "fvec.h"
25#include "fmat.h"
26#include "io/source.h"
27#include "utils/ringbuffer.h"
28#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;
53
54struct _aubio_sampler_t {
55  uint_t samplerate;
56  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
68  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;
83  fvec_t *source_output;
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
96};
97
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)
116{
117  aubio_sampler_t *s = AUBIO_NEW(aubio_sampler_t);
118  if ((sint_t)blocksize < 1) {
119    AUBIO_ERR("sampler: got blocksize %d, but can not be < 1\n", blocksize);
120    goto beach;
121  }
122  s->samplerate = samplerate;
123  s->blocksize = blocksize;
124  s->source = NULL;
125  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
181  return s;
182beach:
183  AUBIO_FREE(s);
184  return NULL;
185}
186
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
239uint_t aubio_sampler_load( aubio_sampler_t * o, const char_t * uri )
240{
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
662  if (o->playing) {
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;
727  }
728}
729
730uint_t aubio_sampler_get_playing ( const aubio_sampler_t * o )
731{
732  return o->playing;
733}
734
735uint_t aubio_sampler_set_playing ( aubio_sampler_t * o, uint_t playing )
736{
737  o->playing = (playing == 1) ? 1 : 0;
738  return 0;
739}
740
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
752uint_t aubio_sampler_play ( aubio_sampler_t * o )
753{
754  return aubio_sampler_set_playing (o, 1);
755}
756
757uint_t aubio_sampler_stop ( aubio_sampler_t * o )
758{
759  return aubio_sampler_set_playing (o, 0);
760}
761
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
788void del_aubio_sampler( aubio_sampler_t * o )
789{
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  }
806  if (o->source) {
807    del_aubio_source(o->source);
808  }
809  AUBIO_FREE(o);
810}
Note: See TracBrowser for help on using the repository browser.