source: src/synth/sampler.c @ f253b03

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

src/synth/sampler.c: clean-up, move first read in reading thread

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