source: src/synth/sampler.c @ a006c5f

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

src/synth/sampler.c: remove debug variable, make sure source_blocksize >= blocksize, print a warning if sample duration is shorter than blocksize

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