- Timestamp:
- Oct 8, 2016, 7:59:41 PM (8 years ago)
- Branches:
- sampler
- Children:
- fefbbd8
- Parents:
- 1b86a8b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/synth/sampler.c
r1b86a8b r88a774c 19 19 */ 20 20 21 #include <assert.h> 21 22 22 23 #include "config.h" … … 25 26 #include "fmat.h" 26 27 #include "io/source.h" 28 #include "utils/ringbuffer.h" 27 29 #include "synth/sampler.h" 28 30 29 31 #define HAVE_THREADS 1 30 #define READER_THREAD_ON 032 #define READER_THREAD_ON 1 31 33 #if 0 32 34 #undef HAVE_THREADS … … 36 38 #include <pthread.h> 37 39 #endif 40 41 typedef 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 48 int check_wrote = 0; 49 50 typedef 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; 38 56 39 57 struct _aubio_sampler_t { 40 58 uint_t samplerate; 41 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 fvec_t *samples; 68 fmat_t *msamples; 69 // reading from a source 42 70 aubio_source_t *source; 43 71 const char_t *uri; … … 54 82 pthread_cond_t read_avail; 55 83 pthread_cond_t read_request; 56 pthread_t open_thread; // file opening thread 84 uint_t source_blocksize; 85 fvec_t *source_output; 86 fmat_t *source_moutput; 87 uint_t channels; 88 // file opening thread 89 pthread_t open_thread; 57 90 pthread_mutex_t open_mutex; 58 91 uint_t waited; // number of frames skipped while opening … … 64 97 #endif 65 98 }; 99 100 static sint_t aubio_sampler_pull_from_source(aubio_sampler_t *s); 101 102 static void aubio_sampler_do_eof(aubio_sampler_t *s); 103 104 static void aubio_sampler_read(aubio_sampler_t *s, fvec_t *output, uint_t *read); 105 static void aubio_sampler_read_from_source(aubio_sampler_t *s, fvec_t *output, uint_t *read); 106 static void aubio_sampler_read_from_table(aubio_sampler_t *s, fvec_t *output, uint_t *read); 66 107 67 108 #ifdef HAVE_THREADS … … 92 133 s->available = 0; 93 134 94 #ifdef HAVE_THREADS 95 s->threaded_read = READER_THREAD_ON; 135 #if 0 // naive mode 136 s->source_blocksize = s->blocksize; 137 s->perfectloop = 0; 138 #elif 0 // threaded mode 139 s->source_blocksize = s->blocksize; 140 // FIXME: perfectloop fails if source_blocksize > 2048 ?! 141 //s->source_blocksize = 4096; //32 * s->blocksize; 142 s->perfectloop = 0; 143 s->threaded_read = 0; 144 #elif 1 // unthreaded ringbuffer mode 145 s->source_blocksize = 2048; //32 * s->blocksize; 146 // FIXME: perfectloop fails if source_blocksize > 2048 ?! 147 //s->source_blocksize = 4096; //32 * s->blocksize; 148 s->perfectloop = 1; 149 #endif 150 151 if (s->perfectloop || s->source_blocksize != s->blocksize) { 152 s->source_output = new_fvec(s->source_blocksize); 153 s->ring = new_aubio_ringbuffer(s->source_blocksize, s->blocksize); 154 } 155 156 #ifdef HAVE_THREADS 96 157 aubio_sampler_open_opening_thread(s); 158 97 159 if (s->threaded_read) { 160 s->source_blocksize = s->blocksize; 161 //s->source_output = new_fvec(s->source_blocksize); 162 s->channels = 1; 163 s->source_moutput = new_fmat(s->source_blocksize, s->channels); 98 164 aubio_sampler_open_reading_thread(s); 165 } else if (0) { 166 s->source_blocksize = s->blocksize; 167 } else { 168 //s->source_blocksize = 16*s->blocksize; 169 //s->source_blocksize = 8192; //s->blocksize; 170 //s->ring = new_aubio_ringbuffer(s->source_blocksize, s->source_blocksize); 99 171 } 100 172 #endif … … 159 231 uint_t ret = AUBIO_FAIL; 160 232 aubio_source_t *oldsource = o->source, *newsource = NULL; 161 newsource = new_aubio_source(uri, o->samplerate, o-> blocksize);233 newsource = new_aubio_source(uri, o->samplerate, o->source_blocksize); 162 234 if (newsource) { 163 235 o->source = newsource; … … 171 243 o->opened = 1; 172 244 ret = AUBIO_OK; 173 //AUBIO_WRN("sampler: loaded %s\n", o->uri); 245 AUBIO_MSG("sampler: loaded %s\n", uri); 246 if (o->waited) { 247 AUBIO_WRN("sampler: loading took %.2fms (%d samples)\n", 1000. * 248 o->waited / (smpl_t)o->samplerate, o->waited); 249 } 174 250 } else { 175 251 o->source = NULL; … … 181 257 o->opened = 0; 182 258 AUBIO_WRN("sampler: failed loading %s\n", uri); 259 } 260 if (o->ring) { 261 AUBIO_WRN("sampler: resetting ringbuffer\n"); 262 aubio_ringbuffer_reset(o->ring); 183 263 } 184 264 return ret; … … 211 291 // cancel previous open_thread 212 292 if (pthread_cancel(o->open_thread)) { 213 AUBIO_WRN("sampler: cancelling open thread failed\n");293 AUBIO_WRN("sampler: failed queuing %s (cancelling existing open thread failed)\n", uri); 214 294 return AUBIO_FAIL; 215 295 } else { 216 AUBIO_WRN("sampler: previous open of %s cancelled while opening %s\n",296 AUBIO_WRN("sampler: cancelled queuing %s (queuing %s now)\n", 217 297 o->next_uri, uri); 218 298 } … … 224 304 } 225 305 if (pthread_mutex_trylock(&o->open_mutex)) { 226 AUBIO_WRN("sampler: failed locking in queue\n");306 AUBIO_WRN("sampler: failed queuing %s (locking failed)\n", uri); 227 307 ret = AUBIO_FAIL; 228 308 goto lock_failed; … … 255 335 256 336 #ifdef HAVE_THREADS 337 338 uint_t aubio_sampler_reading_from_source_ring_fetch(aubio_sampler_t*s); 257 339 void *aubio_sampler_readfn(void *z) { 258 340 aubio_sampler_t *p = z; 259 341 while(1) { 260 342 pthread_mutex_lock(&p->read_mutex); 261 if (1) { 262 // idle 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 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); 263 363 pthread_cond_wait(&p->read_request, &p->read_mutex); 264 364 if (p->read_thread_finish) { … … 273 373 pthread_exit(NULL); 274 374 } 375 376 void *aubio_sampler_readfn_ring(void *z) { 377 aubio_sampler_t *p = z; 378 while(1) { 379 pthread_mutex_lock(&p->read_mutex); 380 if (p->open_thread_running) { 381 //AUBIO_WRN("sampler: readfn(): file is being opened\n"); 382 pthread_cond_signal(&p->read_avail); 383 //pthread_cond_wait(&p->read_request, &p->read_mutex); 384 } else if (p->opened && !p->started && !p->finished) { 385 //AUBIO_WRN("sampler: readfn(): file started\n"); 386 p->available = aubio_sampler_pull_from_source(p); 387 if (p->available < (sint_t)p->source_blocksize) 388 aubio_sampler_do_eof(p); 389 pthread_cond_signal(&p->read_avail); 390 if (!p->finished) { 391 pthread_cond_wait(&p->read_request, &p->read_mutex); 392 } 393 } else { 394 //AUBIO_WRN("sampler: readfn(): idle?\n"); 395 //pthread_cond_signal(&p->read_avail); 396 pthread_cond_wait(&p->read_request, &p->read_mutex); 397 if (p->read_thread_finish) { 398 goto done; 399 } 400 } 401 pthread_mutex_unlock(&p->read_mutex); 402 } 403 done: 404 //AUBIO_WRN("sampler: exiting reading thread\n"); 405 pthread_mutex_unlock(&p->read_mutex); 406 pthread_exit(NULL); 407 } 275 408 #endif 276 409 277 410 void 278 aubio_sampler_fetch_from_source(aubio_sampler_t *o, fvec_t *output, uint_t *read) { 279 if (o->opened == 1 && o->source && !o->finished) 280 aubio_source_do(o->source, output, read); 281 } 411 aubio_sampler_read(aubio_sampler_t *s, fvec_t *output, uint_t *read) { 412 if (s->reading_from == aubio_sampler_reading_from_source) { 413 aubio_sampler_read_from_source(s, output, read); 414 } else if (s->reading_from == aubio_sampler_reading_from_table) { 415 aubio_sampler_read_from_table(s, output, read); 416 } 417 } 418 419 static void aubio_sampler_do_perfectloop(aubio_sampler_t *s); 420 421 static void 422 aubio_sampler_reading_from_source_naive(aubio_sampler_t *s, fvec_t * output, 423 uint_t *read) 424 { 425 // directly read from disk 426 //aubio_source_do(s->source, output, read); 427 s->source_output = output; 428 *read = aubio_sampler_pull_from_source(s); 429 check_wrote += s->source_blocksize; 430 if (*read < s->source_blocksize) { 431 //AUBIO_WRN("sampler: calling go_eof in _read_from_source()\n"); 432 aubio_sampler_do_eof(s); 433 } 434 } 435 436 uint_t 437 aubio_sampler_reading_from_source_ring_fetch(aubio_sampler_t*s) { 438 // read source_blocksize (> blocksize) at once 439 int ring_avail = aubio_ringbuffer_get_available(s->ring); 440 //if (ring_avail < s->blocksize) { 441 uint_t available = 0; 442 if (ring_avail < (sint_t)s->blocksize) { 443 available = aubio_sampler_pull_from_source(s); 444 #if 0 445 //AUBIO_MSG("sampler: got %d / %d fetching from source\n", s->available, 446 // s->source_blocksize); 447 if (s->available == 0) { 448 //aubio_sampler_do_eof(s); 449 //aubio_sampler_do_perfectloop(s, output); 450 } 451 if (s->available < s->source_blocksize) { 452 AUBIO_ERR("sampler: short read from source" 453 " s->available %d, ring_avail %d \n", s->available, ring_avail); 454 //s->eof = 0; 455 //abort(); 456 } 457 #endif 458 if (available > 0) { 459 aubio_ringbuffer_push(s->ring, s->source_output, available); 460 } else { 461 //if (s->playing && !s->finished) 462 //AUBIO_WRN("sampler: not reading anymore should do eof now %d\n", check_wrote); 463 // TODO: move eof fetch now 464 } 465 } 466 return available; 467 } 468 469 uint_t 470 aubio_sampler_write_remaining_ring(aubio_sampler_t *s, fvec_t *output, uint_t wrote); 471 472 static void 473 aubio_sampler_reading_from_source_ring_pull(aubio_sampler_t *s, fvec_t *output, 474 uint_t *read) 475 { 476 // write into output 477 int ring_avail = aubio_ringbuffer_get_available(s->ring); 478 if (ring_avail >= (sint_t)s->blocksize) { 479 //AUBIO_MSG("sampler: pulling %d / %d from ringbuffer\n", s->blocksize, ring_avail); 480 aubio_ringbuffer_pull(s->ring, output, s->blocksize); 481 check_wrote += s->blocksize; 482 *read = s->blocksize; 483 } else { 484 //AUBIO_MSG("sampler: last frame, pulling remaining %d left\n", ring_avail); 485 *read = 0; 486 if (ring_avail > 0) { 487 aubio_ringbuffer_pull(s->ring, output, ring_avail); 488 check_wrote += ring_avail; 489 *read += ring_avail; 490 } 491 aubio_sampler_do_eof(s); 492 aubio_sampler_do_perfectloop(s); 493 *read += aubio_sampler_write_remaining_ring(s, output, ring_avail); 494 } 495 } 496 497 static void 498 aubio_sampler_reading_from_source_ring(aubio_sampler_t *s, fvec_t *output, 499 uint_t *read) 500 { 501 aubio_sampler_reading_from_source_ring_fetch(s); 502 aubio_sampler_reading_from_source_ring_pull(s, output, read); 503 } 504 505 #ifdef HAVE_THREADS 506 static void 507 aubio_sampler_read_from_source_threaded(aubio_sampler_t *s, fvec_t *output, 508 uint_t *read) { 509 // request at least output->length 510 // make sure we have enough samples read from source 511 int available; 512 pthread_mutex_lock(&s->read_mutex); 513 if (!s->opened || s->open_thread_running) { 514 //AUBIO_ERR("sampler: _read_from_source: not opened, signaling read_request\n"); 515 pthread_cond_signal(&s->read_request); 516 available = 0; 517 } else if (!s->finished) { 518 //AUBIO_ERR("sampler: _read_from_source: waiting for read avail %d\n", s->started); 519 pthread_cond_signal(&s->read_request); 520 pthread_cond_wait(&s->read_avail, &s->read_mutex); 521 //AUBIO_ERR("sampler: _read_from_source: %d\n", s->available); 522 available = s->available; 523 } else { 524 //AUBIO_WRN("sampler: _read_from_source: eof\n"); 525 pthread_cond_signal(&s->read_request); 526 available = 0; 527 } 528 pthread_mutex_unlock(&s->read_mutex); 529 //AUBIO_WRN("sampler: got %d available in _read_from_source\n", available); 530 // read -> number of samples read 531 if (available >= (sint_t)s->blocksize) { 532 fvec_copy(s->source_output, output); 533 *read = s->blocksize; 534 } else if (available > 0) { 535 fvec_copy(s->source_output, output); 536 *read = available; 537 } else { 538 fvec_zeros(output); 539 *read = 0; 540 } 541 //*read = s->available; 542 } 543 #endif 282 544 283 545 void 284 aubio_sampler_fetch_from_source_multi(aubio_sampler_t *o, fmat_t *output, uint_t *read) { 285 aubio_source_do_multi(o->source, output, read); 286 } 287 546 aubio_sampler_read_from_source(aubio_sampler_t *s, fvec_t *output, uint_t *read) { 547 #ifdef HAVE_THREADS 548 if (s->threaded_read) { // if threaded 549 if (s->source_blocksize == s->blocksize) { 550 aubio_sampler_read_from_source_threaded(s, output, read); 551 } else { 552 //abort(); 553 } 554 } else 555 #endif 556 { 557 if (s->finished) { 558 *read = 0; 559 } 560 else if (s->source_blocksize == s->blocksize && !s->perfectloop) { 561 aubio_sampler_reading_from_source_naive(s, output, read); 562 } else { 563 aubio_sampler_reading_from_source_ring(s, output, read); 564 } 565 #if 1 566 if (s->loop && s->perfectloop && *read != s->blocksize) { // && s->started && !s->finished) { 567 AUBIO_ERR("sampler: perfectloop but read only %d\n", *read); 568 } 569 #endif 570 } 571 } 572 573 uint_t 574 aubio_sampler_write_remaining_ring(aubio_sampler_t *s, fvec_t *output, uint_t wrote){ 575 if (s->perfectloop && s->loop) { 576 fvec_t tmpout; 577 tmpout.data = output->data + wrote; 578 tmpout.length = s->blocksize - wrote; 579 aubio_ringbuffer_pull(s->ring, &tmpout, tmpout.length); 580 //*read += tmpout.length; 288 581 #if 0 582 int ring_avail = aubio_ringbuffer_get_available(s->ring); 583 AUBIO_WRN("sampler: perfectloop, " 584 "%d left in ring, looping pulled %d more, wrote %d + %d\n", 585 ring_avail, s->available, wrote, tmpout.length); 586 #endif 587 check_wrote += tmpout.length; 588 return tmpout.length; 589 } 590 return 0; 591 } 592 289 593 void 290 aubio_sampler_fetch_from_array(aubio_sampler_t *o, fvec_t *output, uint_t *read) { 291 // TODO 292 } 293 #endif 594 aubio_sampler_do_perfectloop(aubio_sampler_t *s) { 595 // perfectloop fetched new samples from start of source to ringbuffer 596 if (s->perfectloop && s->loop) { 597 s->available = aubio_sampler_pull_from_source(s); 598 if (s->available <= 0) { 599 AUBIO_ERR("sampler: looping but s->available = 0 !\n"); 600 } else { 601 //AUBIO_ERR("sampler: perfectloop fetch and push more\n"); 602 aubio_ringbuffer_push(s->ring, s->source_output, s->available); 603 } 604 } 605 } 606 607 void 608 aubio_sampler_read_from_table(aubio_sampler_t *o, fvec_t *output, uint_t *read) { 609 *read = 0; 610 AUBIO_WRN("sampler: _pull_from_table not implemented for %d, %d, %d", 611 o, output->length, *read); 612 } 613 614 sint_t 615 aubio_sampler_pull_from_source(aubio_sampler_t *s) 616 { 617 // pull source_blocksize samples from source, return available frames 618 uint_t source_read = s->source_blocksize; 619 if (s->source == NULL) { 620 AUBIO_ERR("sampler: trying to fetch on NULL source\n"); 621 return -1; 622 } 623 // do actual reading 624 aubio_source_do(s->source, s->source_output, &source_read); 625 #if 0 626 if (source_read < s->source_blocksize) { 627 //AUBIO_ERR("sampler: _pull_from_source: short read %d < %d\n", source_read, 628 // s->source_blocksize); 629 //aubio_sampler_do_eof(s); 630 if (s->loop) { 631 AUBIO_ERR("sampler: _pull_from_source: loop, should seeking to 0? %d / %d\n", 632 source_read, s->source_blocksize); 633 //aubio_sampler_seek(s, 0); 634 } 635 } 636 //AUBIO_ERR("sampler: _pull_from_source: read %d / %d\n", source_read, length); 637 #endif 638 return source_read; 639 } 640 294 641 295 642 uint_t … … 338 685 aubio_sampler_seek(aubio_sampler_t * o, uint_t pos) 339 686 { 687 //AUBIO_WRN("sampler: seeking to 0\n"); 340 688 uint_t ret = AUBIO_FAIL; 341 689 o->finished = 0; … … 350 698 aubio_sampler_do_eof (aubio_sampler_t * o) 351 699 { 700 //AUBIO_MSG("sampler: calling _do_eof()\n"); 352 701 o->finished = 1; 353 702 o->eof = 1; … … 356 705 } else { 357 706 aubio_sampler_seek(o, 0); 707 //o->finished = 0; 358 708 } 359 709 } … … 363 713 o->eof = 0; 364 714 if (o->opened == 1 && o->playing) { 365 aubio_sampler_fetch_from_source(o, output, read); 715 aubio_sampler_read(o, output, read); 716 //AUBIO_WRN("sampler: _read got %d\n", *read); 366 717 if (*read < o->blocksize) { 367 aubio_sampler_do_eof (o); 718 if (*read > 0 && o->loop) { 719 // TODO pull (hopsize - read) frames 720 } 721 } 722 } else { 723 fvec_zeros(output); 724 *read = 0; 725 } 726 } 727 728 void aubio_sampler_do_multi ( aubio_sampler_t * o, fmat_t * output, uint_t *read) 729 { 730 o->eof = 0; 731 if (o->opened == 1 && o->playing) { 732 //aubio_sampler_read_multi(o, output, read); 733 if (*read < o->blocksize) { 368 734 if (*read > 0) { 369 735 // TODO pull (hopsize - read) frames … … 372 738 } 373 739 } else { 374 fvec_zeros(output);375 *read = 0; //output->length;376 }377 }378 379 void aubio_sampler_do_multi ( aubio_sampler_t * o, fmat_t * output, uint_t *read)380 {381 o->eof = 0;382 if (o->playing) {383 aubio_sampler_fetch_from_source_multi(o, output, read);384 if (*read < o->blocksize) {385 aubio_sampler_do_eof (o);386 if (*read > 0) {387 // TODO pull (hopsize - read) frames388 //memset(... tail , 0)389 }390 }391 } else {392 740 fmat_zeros(output); 393 741 *read = 0; … … 444 792 void del_aubio_sampler( aubio_sampler_t * o ) 445 793 { 794 AUBIO_MSG("sampler: check_wrote: %d\n", check_wrote); 446 795 #ifdef HAVE_THREADS 447 796 // close opening thread … … 450 799 aubio_sampler_close_reading_thread(o); 451 800 #endif 801 //if (o->source_output) { 802 if (o->perfectloop || o->ring) { 803 del_fvec(o->source_output); 804 } 805 if (o->source_moutput) { 806 del_fmat(o->source_moutput); 807 } 808 if (o->ring) { 809 del_aubio_ringbuffer(o->ring); 810 } 452 811 if (o->source) { 453 812 del_aubio_source(o->source);
Note: See TracChangeset
for help on using the changeset viewer.