Changeset 284fe8a for src/effects
- Timestamp:
- Dec 7, 2018, 1:28:55 AM (6 years ago)
- Branches:
- feature/cnn, feature/crepe, feature/timestretch, fix/ffmpeg5, master
- Children:
- e7d4aa0
- Parents:
- 4559863
- git-author:
- Paul Brossier <piem@piem.org> (11/28/16 14:30:40)
- git-committer:
- Paul Brossier <piem@piem.org> (12/07/18 01:28:55)
- Location:
- src/effects
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/effects/timestretch.h
r4559863 r284fe8a 64 64 /** creation of the time stretching object 65 65 66 \param uri path to create the source from67 66 \param method time stretching algorithm ("default") 68 67 \param stretch initial time stretching factor … … 73 72 74 73 */ 75 aubio_timestretch_t *new_aubio_timestretch (const char_t * uri, 76 const char_t * method, smpl_t stretch, uint_t hop_size, uint_t samplerate); 74 aubio_timestretch_t *new_aubio_timestretch (const char_t * method, 75 smpl_t stretch, uint_t hop_size, uint_t samplerate); 76 77 /** push length samples from in to time stretching object 78 79 \param o time stretching object as returned by ::new_aubio_timestretch() 80 \param in input vector of new samples to push to time stretching object 81 \param length number of new samples to push from input vector 82 83 \return number of currently available samples 84 85 */ 86 sint_t aubio_timestretch_push(aubio_timestretch_t * o, fvec_t *in, uint_t length); 87 88 /** get number of currently available samples from time stretching object 89 90 \param o time stretching object as returned by ::new_aubio_timestretch() 91 92 \return number of currently available samples 93 94 */ 95 sint_t aubio_timestretch_get_available(aubio_timestretch_t * o); 77 96 78 97 /** get the latency of the time stretching object, in samples … … 157 176 smpl_t aubio_timestretch_get_transpose (aubio_timestretch_t * o); 158 177 159 /** seek to a posisition the transposition of the time stretching object, in semitones178 /** reset the time stretching object 160 179 161 180 \param o time stretching object as returned by ::new_aubio_timestretch() 162 \param pos position to seek to, in frames163 181 164 \return transposition of the time stretching object, in semitones182 \return 0 on success, non-zero otherwise 165 183 166 184 */ 167 uint_t aubio_timestretch_seek(aubio_timestretch_t * o, uint_t pos); 168 169 uint_t aubio_timestretch_queue (aubio_timestretch_t *p, const char_t *uri, uint_t samplerate); 170 171 uint_t aubio_timestretch_get_opened (aubio_timestretch_t *p); 185 uint_t aubio_timestretch_reset(aubio_timestretch_t * o); 172 186 173 187 #ifdef __cplusplus -
src/effects/timestretch_dummy.c
r4559863 r284fe8a 44 44 45 45 aubio_timestretch_t * 46 new_aubio_timestretch (const char_t * uri UNUSED, const char_t *method UNUSED,46 new_aubio_timestretch (const char_t * method UNUSED, 47 47 smpl_t pitchscale UNUSED, uint_t hop_size UNUSED, uint_t samplerate UNUSED) 48 48 { … … 87 87 } 88 88 89 uint_t aubio_timestretch_seek(aubio_timestretch_t *o UNUSED, uint_t pos UNUSED) { 89 uint_t aubio_timestretch_reset(aubio_timestretch_t *o UNUSED) { 90 return AUBIO_FAIL; 91 } 92 93 sint_t aubio_timestretch_push(aubio_timestretch_t * o UNUSED, fvec_t * in 94 UNUSED, uint_t length UNUSED) { 95 return AUBIO_FAIL; 96 } 97 98 sint_t aubio_timestretch_get_available(aubio_timestretch_t * o UNUSED) { 90 99 return AUBIO_FAIL; 91 100 } -
src/effects/timestretch_rubberband.c
r4559863 r284fe8a 51 51 smpl_t pitchscale; /**< pitch scale */ 52 52 53 aubio_source_t *source;54 uint_t source_hopsize; /**< hop size at which the source is read */55 fvec_t *in;56 uint_t eof;57 58 53 RubberBandState rb; 59 54 RubberBandOptions rboptions; 60 61 uint_t opened;62 const char_t *uri;63 #ifdef HAVE_THREADS64 pthread_t read_thread;65 pthread_mutex_t read_mutex;66 pthread_cond_t read_avail;67 pthread_cond_t read_request;68 pthread_t open_thread;69 pthread_mutex_t open_mutex;70 uint_t open_thread_running;71 sint_t available;72 uint_t started;73 uint_t finish;74 #endif75 55 }; 76 56 … … 78 58 79 59 static void aubio_timestretch_warmup (aubio_timestretch_t * p); 80 static sint_t aubio_timestretch_fetch(aubio_timestretch_t *p, uint_t fetch);81 #ifdef HAVE_THREADS82 static void *aubio_timestretch_readfn(void *p);83 static void *aubio_timestretch_openfn(void *z);84 #endif85 60 86 61 aubio_timestretch_t * 87 new_aubio_timestretch (const char_t * uri, const char_t * mode,88 smpl_t stretchratio, uint_t hopsize,uint_t samplerate)62 new_aubio_timestretch (const char_t * mode, smpl_t stretchratio, uint_t hopsize, 63 uint_t samplerate) 89 64 { 90 65 aubio_timestretch_t *p = AUBIO_NEW (aubio_timestretch_t); 91 66 p->hopsize = hopsize; 92 //p->source_hopsize = 2048;93 p->source_hopsize = hopsize;94 67 p->pitchscale = 1.; 95 68 … … 108 81 } 109 82 110 p->in = new_fvec(p->source_hopsize); 111 112 #ifndef HAVE_THREADS 113 if (aubio_timestretch_queue(p, uri, samplerate)) goto beach; 114 aubio_timestretch_warmup(p); 115 #else 116 p->started = 0; 117 p->finish = 0; 118 p->open_thread_running = 0; 119 //p->uri = uri; 120 p->eof = 0; 121 //p->samplerate = samplerate; 122 //if (aubio_timestretch_open(p, uri, samplerate)) goto beach; 123 pthread_mutex_init(&p->open_mutex, 0); 124 pthread_mutex_init(&p->read_mutex, 0); 125 pthread_cond_init (&p->read_avail, 0); 126 pthread_cond_init (&p->read_request, 0); 127 //AUBIO_WRN("timestretch: creating thread\n"); 128 pthread_create(&p->read_thread, 0, aubio_timestretch_readfn, p); 129 //AUBIO_DBG("timestretch: new_ waiting for warmup, got %d available\n", p->available); 130 pthread_mutex_lock(&p->read_mutex); 131 aubio_timestretch_queue(p, uri, samplerate); 132 #if 0 133 pthread_cond_wait(&p->read_avail, &p->read_mutex); 134 if (!p->opened) { 135 goto beach; 136 } 137 #endif 138 pthread_mutex_unlock(&p->read_mutex); 139 //AUBIO_DBG("timestretch: new_ warm up success, got %d available\n", p->available); 140 #endif 83 p->rb = rubberband_new(samplerate, 1, p->rboptions, p->stretchratio, p->pitchscale); 84 if (!p->rb) goto beach; 85 86 p->samplerate = samplerate; 87 88 //aubio_timestretch_warmup(p); 141 89 142 90 return p; … … 147 95 } 148 96 149 #define HAVE_OPENTHREAD 1150 //#undef HAVE_OPENTHREAD151 152 uint_t153 aubio_timestretch_queue(aubio_timestretch_t *p, const char_t* uri, uint_t samplerate)154 {155 #ifdef HAVE_THREADS156 #ifdef HAVE_OPENTHREAD157 if (p->open_thread_running) {158 #if 1159 if (pthread_cancel(p->open_thread)) {160 AUBIO_WRN("timestretch: cancelling open thread failed\n");161 return AUBIO_FAIL;162 } else {163 AUBIO_WRN("timestretch: previous open of '%s' cancelled\n", p->uri);164 }165 p->open_thread_running = 0;166 #else167 void *threadfn;168 if (pthread_join(p->open_thread, &threadfn)) {169 AUBIO_WRN("timestretch: failed joining existing open thread\n");170 return AUBIO_FAIL;171 }172 #endif173 }174 //AUBIO_WRN("timestretch: queueing %s\n", uri);175 //pthread_mutex_lock(&p->read_mutex);176 p->opened = 0;177 p->started = 0;178 p->available = 0;179 p->uri = uri;180 p->samplerate = samplerate;181 //AUBIO_WRN("timestretch: creating thread\n");182 pthread_create(&p->open_thread, 0, aubio_timestretch_openfn, p);183 #endif184 //pthread_mutex_unlock(&p->read_mutex);185 return AUBIO_OK;186 }187 188 uint_t189 aubio_timestretch_open(aubio_timestretch_t *p, const char_t* uri, uint_t samplerate)190 {191 uint_t err = AUBIO_FAIL;192 p->available = 0;193 pthread_mutex_lock(&p->open_mutex);194 p->open_thread_running = 1;195 #else196 uint_t err = AUBIO_FAIL;197 #endif198 p->opened = 0;199 if (p->source) del_aubio_source(p->source);200 p->source = new_aubio_source(uri, samplerate, p->source_hopsize);201 if (!p->source) goto fail;202 p->uri = uri;203 p->samplerate = aubio_source_get_samplerate(p->source);204 p->eof = 0;205 206 if (p->rb == NULL) {207 AUBIO_WRN("timestretch: creating with stretch: %.2f pitchscale: %.2f\n",208 p->stretchratio, p->pitchscale);209 p->rb = rubberband_new(p->samplerate, 1, p->rboptions, p->stretchratio, p->pitchscale);210 //rubberband_set_debug_level(p->rb, 10);211 rubberband_set_max_process_size(p->rb, p->source_hopsize);212 } else {213 if (samplerate != p->samplerate) {214 AUBIO_WRN("timestretch: samplerate change requested, but not implemented\n");215 }216 rubberband_reset(p->rb);217 }218 p->opened = 1;219 err = AUBIO_OK;220 goto unlock;221 fail:222 p->opened = 2;223 AUBIO_ERR("timestretch: opening %s failed\n", uri);224 unlock:225 #ifdef HAVE_THREADS226 p->open_thread_running = 0;227 pthread_mutex_unlock(&p->open_mutex);228 //AUBIO_WRN("timestretch: failed opening %s at %dHz\n", uri, samplerate);229 #endif230 return err;231 }232 233 #ifdef HAVE_THREADS234 void *235 aubio_timestretch_openfn(void *z) {236 aubio_timestretch_t *p = z;237 int oldtype;238 pthread_setcancelstate(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);239 //AUBIO_WRN("timestretch: creating thread\n");240 void *ret;241 uint_t err = aubio_timestretch_open(p, p->uri, p->samplerate);242 ret = &err;243 pthread_exit(ret);244 }245 #endif246 247 uint_t248 aubio_timestretch_get_opened(aubio_timestretch_t *p)249 {250 if (p == NULL) return 0;251 else return p->opened;252 }253 254 #ifdef HAVE_THREADS255 void *256 aubio_timestretch_readfn(void *z)257 {258 aubio_timestretch_t *p = z;259 //AUBIO_WRN("timestretch: entering thread with %s at %dHz\n", p->uri, p->samplerate);260 while(1) { //p->available < (int)p->hopsize && p->eof != 1) {261 //AUBIO_WRN("timestretch: locking in readfn\n");262 pthread_mutex_lock(&p->read_mutex);263 #if 1264 if (p->opened == 2) {265 pthread_cond_signal(&p->read_avail);266 } else267 if (p->opened == 0) {268 #ifdef HAVE_OPENTHREAD269 //(!aubio_timestretch_open(p, p->uri, p->samplerate)) {270 void * threadfn;271 if (p->open_thread_running && pthread_join(p->open_thread, &threadfn)) {272 AUBIO_WRN("timestretch: failed to join opening thread %s at %dHz in thread "273 "(opened: %d, playing: %d, eof: %d)\n",274 p->uri, p->samplerate, p->opened, p->started, p->eof);275 }276 #else277 //AUBIO_WRN("timestretch: opening source %s\n", p->uri);278 if (!aubio_timestretch_open(p, p->uri, p->samplerate)) {279 AUBIO_WRN("timestretch: opened %s at %dHz in thread "280 "(opened: %d, playing: %d, eof: %d)\n",281 p->uri, p->samplerate, p->opened, p->started, p->eof);282 //pthread_cond_signal(&p->read_avail);283 } else {284 AUBIO_WRN("timestretch: failed opening %s, exiting thread\n", p->uri);285 //pthread_cond_signal(&p->read_avail);286 //pthread_mutex_unlock(&p->read_mutex);287 //goto end;288 }289 #endif290 } else291 if (!p->started && !p->eof) {292 #endif293 // fetch the first few samples and mark as started294 aubio_timestretch_warmup(p);295 pthread_cond_signal(&p->read_avail);296 //pthread_cond_wait(&p->read_request, &p->read_mutex);297 p->started = 1;298 } else if (!p->eof) {299 // fetch at least p->hopsize stretched samples300 p->available = aubio_timestretch_fetch(p, p->hopsize);301 // signal available frames302 pthread_cond_signal(&p->read_avail);303 if (p->eof != 1) {304 // the end of file was not reached yet, wait for the next read_request305 pthread_cond_wait(&p->read_request, &p->read_mutex);306 } else {307 // eof was reached, do not wait for a read request and mark as stopped308 p->started = 0;309 }310 } else {311 //pthread_cond_signal(&p->read_avail);312 pthread_cond_wait(&p->read_request, &p->read_mutex);313 //AUBIO_WRN("timestretch: finished idle in readfn\n");314 if (p->finish) pthread_exit(NULL);315 }316 //AUBIO_WRN("timestretch: unlocking in readfn\n");317 pthread_mutex_unlock(&p->read_mutex);318 }319 end:320 //AUBIO_WRN("timestretch: exiting readfn\n");321 pthread_exit(NULL);322 }323 #endif324 325 97 static void 326 98 aubio_timestretch_warmup (aubio_timestretch_t * p) … … 329 101 //AUBIO_WRN("timestretch: warming-up\n"); 330 102 unsigned int latency = MAX(p->hopsize, rubberband_get_latency(p->rb)); 331 #ifdef HAVE_THREADS 332 p->available = aubio_timestretch_fetch(p, latency);333 #else 334 aubio_timestretch_fetch(p, latency);335 #endif 336 //AUBIO_WRN("timestretch: warmup got %d\n", latency);103 fvec_t *input = new_fvec(p->hopsize); 104 while (aubio_timestretch_push(p, input, input->length) < (int)latency) { 105 //sint_t available = aubio_timestretch_get_available(p); 106 //AUBIO_WRN("timestretch: warmup got %d, latency: %d\n", available, latency); 107 } 108 del_fvec(input); 337 109 } 338 110 … … 340 112 del_aubio_timestretch (aubio_timestretch_t * p) 341 113 { 342 #ifdef HAVE_THREADS343 void *threadfn;344 //AUBIO_WRN("timestretch: entering delete\n");345 if (p->open_thread_running) {346 if (pthread_cancel(p->open_thread)) {347 AUBIO_WRN("timestretch: cancelling open thread failed\n");348 }349 if (pthread_join(p->open_thread, &threadfn)) {350 AUBIO_WRN("timestretch: joining open thread failed\n");351 }352 }353 if (!p->opened) goto cleanup;354 pthread_mutex_lock(&p->read_mutex);355 p->finish = 1;356 pthread_cond_signal(&p->read_request);357 //pthread_cond_wait(&p->read_avail, &p->read_mutex);358 pthread_mutex_unlock(&p->read_mutex);359 if ((p->eof == 0) && (pthread_cancel(p->read_thread))) {360 AUBIO_WRN("timestretch: cancelling thread failed\n");361 }362 if (pthread_join(p->read_thread, &threadfn)) {363 AUBIO_WRN("timestretch: joining thread failed\n");364 }365 pthread_mutex_destroy(&p->read_mutex);366 pthread_cond_destroy(&p->read_avail);367 pthread_cond_destroy(&p->read_request);368 cleanup:369 #endif370 if (p->in) del_fvec(p->in);371 if (p->source) del_aubio_source(p->source);372 114 if (p->rb) { 373 115 rubberband_delete(p->rb); … … 451 193 452 194 sint_t 453 aubio_timestretch_fetch(aubio_timestretch_t *p, uint_t length) 454 { 455 uint_t source_read = p->source_hopsize; 456 if (p->source == NULL) { 457 AUBIO_ERR("timestretch: trying to fetch on NULL source\n"); 458 return 0; 459 } 460 // read more samples from source until we have enough available or eof is reached 195 aubio_timestretch_push(aubio_timestretch_t *p, fvec_t *input, uint_t length) 196 { 197 // push new samples to rubberband, return available 198 int available; 199 int eof = (input->length != length) ? 1 : 0; 200 rubberband_process(p->rb, (const float* const*)&(input->data), length, eof); 201 available = rubberband_available(p->rb); 202 //AUBIO_WRN("timestretch: processed %d, %d available, eof: %d\n", 203 // length, available, eof); 204 return available; 205 } 206 207 sint_t 208 aubio_timestretch_get_available(aubio_timestretch_t *p) { 209 return rubberband_available(p->rb); 210 } 211 212 void 213 aubio_timestretch_do(aubio_timestretch_t * p, fvec_t * out, uint_t * read) 214 { 215 // now retrieve the samples and write them into out->data 461 216 int available = rubberband_available(p->rb); 462 while ((available < (int)length) && (p->eof == 0)) { 463 aubio_source_do(p->source, p->in, &source_read); 464 if (source_read < p->source_hopsize) { 465 p->eof = 1; 466 } 467 rubberband_process(p->rb, (const float* const*)&(p->in->data), source_read, p->eof); 468 available = rubberband_available(p->rb); 469 } 470 return available; 471 } 472 473 void 474 aubio_timestretch_do (aubio_timestretch_t * p, fvec_t * out, uint_t * read) 475 { 476 #ifndef HAVE_THREADS 477 int available = aubio_timestretch_fetch(p, p->hopsize); 478 #else /* HAVE_THREADS */ 479 int available; 480 pthread_mutex_lock(&p->read_mutex); 481 #if 1 482 if (!p->opened) { 483 // this may occur if _do was was called while being opened 484 //AUBIO_WRN("timestretch: calling _do before opening a file\n"); 485 pthread_cond_signal(&p->read_request); 486 //available = 0; 487 //pthread_cond_wait(&p->read_avail, &p->read_mutex); 488 available = 0; //p->available; 489 } else 490 #endif 491 if (p->eof != 1) { 492 //AUBIO_WRN("timestretch: calling _do after opening a file\n"); 493 // signal a read request 494 pthread_cond_signal(&p->read_request); 495 // wait for an available signal 496 pthread_cond_wait(&p->read_avail, &p->read_mutex); 497 available = p->available; 498 } else { 499 available = rubberband_available(p->rb); 500 //AUBIO_WRN("timestretch: reached eof (%d/%d)\n", p->hopsize, available); 501 } 502 pthread_mutex_unlock(&p->read_mutex); 503 #endif /* HAVE_THREADS */ 504 // now retrieve the samples and write them into out->data 505 if (available >= (int)p->hopsize) { 506 rubberband_retrieve(p->rb, (float* const*)&(out->data), p->hopsize); 507 *read = p->hopsize; 217 if (available >= (int)out->length) { 218 rubberband_retrieve(p->rb, (float* const*)&(out->data), out->length); 219 *read = out->length; 508 220 } else if (available > 0) { 509 221 // this occurs each time the end of file is reached 510 222 //AUBIO_WRN("timestretch: short read\n"); 511 223 rubberband_retrieve(p->rb, (float* const*)&(out->data), available); 224 fvec_t zeros; zeros.length = out->length - available; zeros.data = out->data + available; 225 fvec_zeros(&zeros); 512 226 *read = available; 513 227 } else { … … 516 230 *read = 0; 517 231 } 518 #ifdef HAVE_THREADS 519 //pthread_mutex_unlock(&p->read_mutex); 520 #endif 521 } 522 523 uint_t 524 aubio_timestretch_seek (aubio_timestretch_t *p, uint_t pos) 232 } 233 234 uint_t 235 aubio_timestretch_reset(aubio_timestretch_t *p) 525 236 { 526 237 uint_t err = AUBIO_OK; 527 #if HAVE_THREADS528 if (p == NULL) {529 AUBIO_WRN("seeking but object not set yet (ignoring)\n");530 return AUBIO_FAIL;531 }532 pthread_mutex_lock(&p->read_mutex);533 if (p->open_thread_running) {534 //AUBIO_WRN("seeking but opening thread not completed yet (ignoring)\n");535 err = AUBIO_OK;536 goto beach;537 }538 if (!p->opened || !p->source) {539 //AUBIO_WRN("timestretch: seeking but source not opened yet (ignoring)\n");540 err = AUBIO_OK;541 goto beach;542 }543 #endif544 p->eof = 0;545 238 if (p->rb) { 546 239 rubberband_reset(p->rb); 547 240 } 548 #ifdef HAVE_THREADS 549 #ifdef HAVE_OPENTHREAD 550 pthread_mutex_lock(&p->open_mutex); 241 return err; 242 } 243 551 244 #endif 552 #endif553 if (p->source) {554 err = aubio_source_seek(p->source, pos);555 } else {556 AUBIO_WRN("timestretch: seeking but p->source not created?!\n");557 err = AUBIO_FAIL;558 goto beach;559 }560 #if HAVE_THREADS561 pthread_mutex_unlock(&p->open_mutex);562 p->available = 0;563 p->started = 1;564 beach:565 pthread_mutex_unlock(&p->read_mutex);566 #else567 beach:568 #endif569 return err;570 }571 572 #endif
Note: See TracChangeset
for help on using the changeset viewer.