Changes in / [b762f8d:b201912]
- Files:
-
- 14 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
.travis.yml
rb762f8d rb201912 42 42 osx_image: xcode8 43 43 compiler: clang 44 env: WAFOPTS="--with-target-platform=ios --disable-avcodec --disable-sndfile " AUBIO_NOTESTS=144 env: WAFOPTS="--with-target-platform=ios --disable-avcodec --disable-sndfile --disable-samplerate --disable-rubberband" AUBIO_NOTESTS=1 45 45 - language: C 46 46 os: osx 47 47 osx_image: xcode8 48 48 compiler: clang 49 env: WAFOPTS="-- with-target-platform=iosimulator --disable-avcodec --disable-sndfile" AUBIO_NOTESTS=149 env: WAFOPTS="--enable-fat --disable-avcodec --disable-sndfile --disable-samplerate --disable-rubberband" AUBIO_NOTESTS=1 50 50 - language: C 51 51 os: osx … … 57 57 osx_image: xcode8.2 58 58 compiler: clang 59 env: WAFOPTS="--with-target-platform=ios --disable-avcodec --disable-sndfile " AUBIO_NOTESTS=159 env: WAFOPTS="--with-target-platform=ios --disable-avcodec --disable-sndfile --disable-samplerate --disable-rubberband" AUBIO_NOTESTS=1 60 60 - language: C 61 61 os: osx 62 62 osx_image: xcode8.2 63 63 compiler: clang 64 env: WAFOPTS="--with-target-platform=iosimulator --disable-avcodec --disable-sndfile " AUBIO_NOTESTS=164 env: WAFOPTS="--with-target-platform=iosimulator --disable-avcodec --disable-sndfile --disable-samplerate --disable-rubberband" AUBIO_NOTESTS=1 65 65 66 66 # use trusty … … 81 81 - libasound2-dev 82 82 - libfftw3-dev 83 - librubberband-dev 83 84 - sox 84 85 … … 90 91 brew install ffmpeg 91 92 brew install libsndfile 93 brew install libsamplerate 94 brew install rubberband 92 95 export PATH="$HOME/Library/Python/2.7/bin/:$PATH" 93 96 fi; -
python/lib/gen_code.py
rb762f8d rb201912 20 20 'method': '"default"', 21 21 'uri': '"none"', 22 'transpose': '0.', 23 'maxwrite': 1024, 24 'maxrequest': 1024, 22 25 } 23 26 … … 83 86 'filterbank': 'self->n_filters', 84 87 'tss': 'self->buf_size', 88 'pitchshift': 'self->hop_size', 89 'ringbuffer': 'self->maxrequest', 85 90 } 86 91 … … 95 100 'wavetable': 'self->hop_size', 96 101 'tss': 'self->buf_size / 2 + 1', 102 'pitchshift': 'self->hop_size', 103 'ringbuffer': 'self->maxwrite', 97 104 } 98 105 … … 270 277 if p['type'] == 'char_t*': 271 278 return self.check_valid_char(p) 279 if p['type'] == 'smpl_t': 280 return self.check_valid_smpl(p) 272 281 else: 273 282 print ("ERROR, no idea how to check %s for validity" % p['type']) … … 290 299 self->{name} = {defval}; 291 300 if ({name} != NULL) {{ 301 self->{name} = {name}; 302 }} 303 """.format(defval = aubiodefvalue[name], name = name) 304 305 def check_valid_smpl(self, p): 306 name = p['name'] 307 return """ 308 self->{name} = {defval}; 309 if ({name} != 0.) {{ 292 310 self->{name} = {name}; 293 311 }} -
python/lib/gen_external.py
rb762f8d rb201912 38 38 'source_avcodec', 39 39 'source_wavread', 40 #'sampler',41 40 'audio_unit', 42 41 'spectral_whitening', 42 'timestretch', # TODO fix parsing of uint_t *read in _do 43 'sampler', # TODO fix parsing of uint_t *read in _do 44 'ringbuffer', 43 45 ] 44 46 -
python/lib/moresetuptools.py
rb762f8d rb201912 80 80 'libswresample', 'libavresample', 81 81 'sndfile', 82 'rubberband', 82 83 #'fftw3f', 83 84 ] … … 101 102 if 'samplerate' in ext.libraries: 102 103 ext.define_macros += [('HAVE_SAMPLERATE', 1)] 104 if 'rubberband' in ext.libraries: 105 ext.define_macros += [('HAVE_RUBBERBAND', 1)] 103 106 if 'fftw3f' in ext.libraries: 104 107 ext.define_macros += [('HAVE_FFTW3F', 1)] -
src/aubio.h
rb762f8d rb201912 219 219 #include "pitch/pitchspecacf.h" 220 220 #include "tempo/beattracking.h" 221 #include "effects/pitchshift.h" 222 #include "effects/timestretch.h" 221 223 #include "utils/scale.h" 222 224 #include "utils/hist.h" 225 #include "utils/ringbuffer.h" 223 226 #endif 224 227 -
src/io/source_avcodec.c
rb762f8d rb201912 61 61 #define AUBIO_AVCODEC_MAX_BUFFER_SIZE FF_MIN_BUFFER_SIZE 62 62 63 #ifdef HAVE_PTHREAD_H 64 // Global mutex to make sure avcodec_open2 is not called simultaneously in a 65 // multithreaded environment. Comment the following define if no lock required. 66 #define HAVE_AUBIO_AVCODEC_MUTEX 67 #include <pthread.h> 68 pthread_mutex_t aubio_avcodec_mutex = PTHREAD_MUTEX_INITIALIZER; 69 #endif /* HAVE_PTHREAD_H */ 70 63 71 struct _aubio_source_avcodec_t { 64 72 uint_t hop_size; … … 87 95 uint_t eof; 88 96 uint_t multi; 97 uint_t has_network_url; 89 98 }; 90 99 … … 101 110 av_url_split(proto, proto_size, authorization, authorization_size, hostname, 102 111 hostname_size, port_ptr, uripath, path_size, s->path); 112 s->has_network_url = 0; 103 113 if (strlen(proto)) { 104 return1;105 } 106 return 0;114 s->has_network_url = 1; 115 } 116 return s->has_network_url; 107 117 } 108 118 … … 113 123 AVCodecContext *avCodecCtx = s->avCodecCtx; 114 124 AVFrame *avFrame = s->avFrame; 125 AVDictionary *streamopts = 0; 115 126 sint_t selected_stream = -1; 116 127 #if FF_API_LAVF_AVCTX … … 140 151 strncpy(s->path, path, strnlen(path, PATH_MAX) + 1); 141 152 153 #ifdef HAVE_AUBIO_AVCODEC_MUTEX 154 pthread_mutex_lock(&aubio_avcodec_mutex); 155 #endif /* HAVE_AUBIO_AVCODEC_MUTEX */ 156 142 157 // register all formats and codecs 143 158 av_register_all(); … … 148 163 149 164 // try opening the file and get some info about it 165 if (s->has_network_url) { 166 if (av_dict_set(&streamopts, "timeout", "1000000", 0)) { // in microseconds 167 AUBIO_WRN("source_avcodec: Failed setting timeout to 1000000 for %s\n", s->path); 168 } else { 169 AUBIO_WRN("source_avcodec: Setting timeout to 1000000 for %s\n", s->path); 170 } 171 } 150 172 avFormatCtx = NULL; 151 if ( (err = avformat_open_input(&avFormatCtx, s->path, NULL, NULL) ) < 0 ) {173 if ( (err = avformat_open_input(&avFormatCtx, s->path, NULL, &streamopts) ) < 0 ) { 152 174 char errorstr[256]; 153 175 av_strerror (err, errorstr, sizeof(errorstr)); … … 237 259 } 238 260 261 #ifdef HAVE_AUBIO_AVCODEC_MUTEX 262 pthread_mutex_unlock(&aubio_avcodec_mutex); 263 #endif /* HAVE_AUBIO_AVCODEC_MUTEX */ 264 239 265 /* get input specs */ 240 266 s->input_samplerate = avCodecCtx->sample_rate; … … 277 303 //av_log_set_level(AV_LOG_QUIET); 278 304 305 av_dict_free(&streamopts); 279 306 return s; 280 307 281 308 beach: 309 if (streamopts != 0) av_dict_free(&streamopts); 282 310 //AUBIO_ERR("can not read %s at samplerate %dHz with a hop_size of %d\n", 283 311 // s->path, s->samplerate, s->hop_size); 312 #ifdef HAVE_AUBIO_AVCODEC_MUTEX 313 pthread_mutex_unlock(&aubio_avcodec_mutex); 314 #endif /* HAVE_AUBIO_AVCODEC_MUTEX */ 284 315 del_aubio_source_avcodec(s); 285 316 return NULL; -
src/synth/sampler.c
rb762f8d rb201912 1 1 /* 2 Copyright (C) 2003-201 3Paul Brossier <piem@aubio.org>2 Copyright (C) 2003-2017 Paul Brossier <piem@aubio.org> 3 3 4 4 This file is part of aubio. … … 19 19 */ 20 20 21 #include <assert.h> 21 22 22 23 #include "aubio_priv.h" … … 24 25 #include "fmat.h" 25 26 #include "io/source.h" 27 #include "utils/ringbuffer.h" 28 #include "effects/timestretch.h" 26 29 #include "synth/sampler.h" 30 31 #ifdef HAVE_PTHREAD_H 32 #define HAVE_THREADS 1 33 #include <pthread.h> 34 #else 35 #ifdef _MSC_VER 36 #pragma message ("WARNING: compiling sampler without threading") 37 #else 38 #warning "compiling sampler without threading" 39 #endif 40 #endif 41 42 typedef enum { 43 aubio_sampler_reading_from_source, 44 aubio_sampler_reading_from_table, 45 aubio_sampler_n_reading_methods 46 } aubio_sampler_reading_method; 47 48 49 typedef enum { 50 aubio_sampler_interp_pitchtime, 51 aubio_sampler_interp_quad, 52 aubio_sampler_interp_lin, 53 aubio_sampler_n_interp_methods 54 } aubio_sampler_interp_method; 27 55 28 56 struct _aubio_sampler_t { 29 57 uint_t samplerate; 30 58 uint_t blocksize; 59 // current reading mode (can be a file or an array) 60 uint_t reading_from; 61 // current interpolation mode (can be quadratic, timestretch, ...) 62 uint_t interp; 63 aubio_ringbuffer_t *ring; 64 uint_t perfectloop; 65 uint_t eof_remaining; 66 // reading from a table 67 fvec_t *table; 68 uint_t table_index; 69 // reading from a source 31 70 aubio_source_t *source; 32 fvec_t *source_output;33 fmat_t *source_output_multi;34 71 char_t *uri; 35 72 uint_t playing; 73 uint_t opened; 74 uint_t loop; 75 uint_t finished; // end of file was reached 76 uint_t eof; // end of file is now 77 // time stretching 78 aubio_timestretch_t *ts; 79 sint_t available; // number of samples currently available 80 uint_t started; // source warmed up 81 // source 82 uint_t source_blocksize; 83 uint_t channels; 84 fvec_t *source_output; 85 fmat_t *source_moutput; 86 //fvec_t *source_output_tmp; 87 //uint_t last_read; 88 uint_t threaded_read; // use reading thread? 89 #ifdef HAVE_THREADS 90 // file reading thread 91 pthread_t read_thread; 92 pthread_mutex_t read_mutex; 93 pthread_cond_t read_avail; 94 pthread_cond_t read_request; 95 // file opening thread 96 pthread_t open_thread; 97 pthread_mutex_t open_mutex; 98 uint_t waited; // number of frames skipped while opening 99 char_t *next_uri; 100 uint_t open_thread_running; 101 uint_t read_thread_finish; // flag to tell reading thread to exit 102 #endif 36 103 }; 37 104 38 aubio_sampler_t *new_aubio_sampler(uint_t samplerate, uint_t blocksize) 105 static sint_t aubio_sampler_pull_from_source(aubio_sampler_t *s); 106 107 static void aubio_sampler_do_eof(aubio_sampler_t *s); 108 109 static void aubio_sampler_read(aubio_sampler_t *s, fvec_t *output, uint_t *read); 110 static void aubio_sampler_read_from_source(aubio_sampler_t *s, fvec_t *output, uint_t *read); 111 static void aubio_sampler_read_from_table(aubio_sampler_t *s, fvec_t *output, uint_t *read); 112 113 #ifdef HAVE_THREADS 114 static void *aubio_sampler_openfn(void *p); 115 static void *aubio_sampler_readfn(void *p); 116 static void aubio_sampler_open_opening_thread(aubio_sampler_t *o); 117 static void aubio_sampler_open_reading_thread(aubio_sampler_t *o); 118 static void aubio_sampler_close_opening_thread(aubio_sampler_t *o); 119 static void aubio_sampler_close_reading_thread(aubio_sampler_t *o); 120 #endif 121 122 aubio_sampler_t *new_aubio_sampler(uint_t blocksize, uint_t samplerate) 39 123 { 40 124 aubio_sampler_t *s = AUBIO_NEW(aubio_sampler_t); … … 45 129 s->samplerate = samplerate; 46 130 s->blocksize = blocksize; 47 s->source_output = new_fvec(blocksize);48 s->source_output_multi = new_fmat(4, blocksize);49 131 s->source = NULL; 50 132 s->playing = 0; 133 s->loop = 0; 134 s->uri = NULL; 135 s->finished = 1; 136 s->eof = 0; 137 s->opened = 0; 138 s->available = 0; 139 140 s->perfectloop = 0; 141 #if 0 // naive mode 142 s->source_blocksize = s->blocksize; 143 #elif 0 // threaded mode, no ringbuffer 144 s->source_blocksize = s->blocksize; 145 s->threaded_read = 1; 146 #elif 0 // unthreaded, with ringbuffer 147 s->source_blocksize = 2048; //32 * s->blocksize; 148 s->perfectloop = 1; 149 #elif 1 // threaded with ringhbuffer 150 s->source_blocksize = 2048; //32 * s->blocksize; 151 s->perfectloop = 1; 152 #endif 153 154 #ifdef HAVE_THREADS 155 // disabled for now 156 s->threaded_read = 0; 157 #else 158 s->threaded_read = 0; 159 #endif 160 161 s->perfectloop = 1; 162 163 if (s->source_blocksize < s->blocksize) { 164 s->source_blocksize = s->blocksize; 165 } 166 // FIXME: perfectloop fails if source_blocksize > 2048 with source_avcodec 167 //s->source_blocksize = 8192; 168 169 if (s->perfectloop || s->source_blocksize != s->blocksize) { 170 s->ring = new_aubio_ringbuffer(s->source_blocksize * 2, s->blocksize); 171 } 172 if (s->threaded_read || s->perfectloop || s->ring) 173 s->source_output = new_fvec(s->source_blocksize); 174 //s->channels = 1; 175 //s->source_moutput = new_fmat(s->source_blocksize, s->channels); 176 177 #ifdef HAVE_THREADS 178 aubio_sampler_open_opening_thread(s); 179 180 if (s->threaded_read) { 181 //AUBIO_WRN("sampler: starting reading thread\n"); 182 aubio_sampler_open_reading_thread(s); 183 } 184 #endif 185 186 #if 0 187 s->reading_from = aubio_sampler_reading_from_table; 188 s->perfectloop = 1; 189 s->threaded_read = 0; 190 s->opened = 1; 191 s->finished = 1; 192 s->table_index = 0; 193 #endif 194 195 s->ts = new_aubio_timestretch("default", 1., s->blocksize, s->samplerate); 196 //s->source_output_tmp = new_fvec(s->source_blocksize); 197 //s->last_read = 0; 198 51 199 return s; 52 200 beach: … … 55 203 } 56 204 205 #ifdef HAVE_THREADS 206 void aubio_sampler_open_opening_thread(aubio_sampler_t *s) { 207 pthread_mutex_init(&s->open_mutex, 0); 208 s->waited = 0; 209 s->open_thread = 0; 210 s->open_thread_running = 0; 211 } 212 213 void aubio_sampler_open_reading_thread(aubio_sampler_t *s) { 214 s->read_thread_finish = 0; 215 pthread_mutex_init(&s->read_mutex, 0); 216 pthread_cond_init (&s->read_avail, 0); 217 pthread_cond_init (&s->read_request, 0); 218 pthread_create(&s->read_thread, 0, aubio_sampler_readfn, s); 219 } 220 221 void aubio_sampler_close_opening_thread(aubio_sampler_t *o) { 222 // clean up opening thread 223 void *threadret; 224 if (!o->open_thread) return; 225 pthread_mutex_destroy(&o->open_mutex); 226 if (o->open_thread_running) { 227 if (pthread_cancel(o->open_thread)) { 228 AUBIO_WRN("sampler: cancelling file opening thread failed\n"); 229 } 230 } 231 if (o->open_thread && pthread_join(o->open_thread, &threadret)) { 232 AUBIO_WRN("sampler: joining file opening thread failed\n"); 233 } 234 pthread_mutex_destroy(&o->open_mutex); 235 o->open_thread = 0; 236 } 237 238 void aubio_sampler_close_reading_thread(aubio_sampler_t *o) { 239 // clean up reading thread 240 void *threadret; 241 if (!o->read_thread) return; 242 o->read_thread_finish = 1; 243 pthread_cond_signal(&o->read_request); 244 if (pthread_cancel(o->read_thread)) { 245 AUBIO_WRN("sampler: cancelling file reading thread failed\n"); 246 } 247 if (pthread_join(o->read_thread, &threadret)) { 248 AUBIO_WRN("sampler: joining file reading thread failed\n"); 249 } 250 pthread_mutex_destroy(&o->read_mutex); 251 pthread_cond_destroy(&o->read_avail); 252 pthread_cond_destroy(&o->read_request); 253 o->read_thread = 0; 254 } 255 #endif 256 57 257 uint_t aubio_sampler_load( aubio_sampler_t * o, const char_t * uri ) 58 258 { 59 if (o->source) del_aubio_source(o->source); 60 61 if (o->uri) AUBIO_FREE(o->uri); 62 o->uri = AUBIO_ARRAY(char_t, strnlen(uri, PATH_MAX)); 63 strncpy(o->uri, uri, strnlen(uri, PATH_MAX)); 64 65 o->source = new_aubio_source(uri, o->samplerate, o->blocksize); 66 if (o->source) return 0; 67 AUBIO_ERR("sampler: failed loading %s", uri); 68 return 1; 69 } 70 71 void aubio_sampler_do ( aubio_sampler_t * o, const fvec_t * input, fvec_t * output) 72 { 73 uint_t read = 0, i; 259 uint_t ret = AUBIO_FAIL; 260 aubio_source_t *oldsource = o->source, *newsource = NULL; 261 newsource = new_aubio_source(uri, o->samplerate, o->source_blocksize); 262 if (newsource) { 263 uint_t duration = aubio_source_get_duration(newsource); 264 if (duration < o->blocksize) { 265 AUBIO_WRN("sampler: %s is %d frames long, but blocksize is %d\n", 266 uri, duration, o->blocksize); 267 } 268 o->source = newsource; 269 if (oldsource) del_aubio_source(oldsource); 270 if (o->samplerate == 0) { 271 o->samplerate = aubio_source_get_samplerate(o->source); 272 } 273 if (o->uri) AUBIO_FREE(o->uri); 274 o->uri = AUBIO_ARRAY(char_t, strnlen(uri, PATH_MAX) + 1); 275 strncpy(o->uri, uri, strnlen(uri, PATH_MAX) + 1); 276 o->finished = 0; 277 o->eof = 0; 278 o->eof_remaining = 0; 279 o->opened = 1; 280 ret = AUBIO_OK; 281 AUBIO_MSG("sampler: loaded %s\n", uri); 282 #ifdef HAVE_THREADS 283 if (o->waited) { 284 AUBIO_WRN("sampler: %.2fms (%d samples) taken to load %s\n", 1000. * 285 o->waited / (smpl_t)o->samplerate, o->waited, o->uri); 286 } 287 #endif 288 } else { 289 o->source = NULL; 290 if (oldsource) del_aubio_source(oldsource); 291 o->playing = 0; 292 o->uri = NULL; 293 o->finished = 1; 294 o->eof = 0; 295 o->eof_remaining = 0; 296 o->opened = 0; 297 AUBIO_WRN("sampler: failed loading %s\n", uri); 298 } 299 if (o->ring) { 300 //AUBIO_WRN("sampler: resetting ringbuffer\n"); 301 aubio_ringbuffer_reset(o->ring); 302 } 303 return ret; 304 } 305 306 #ifdef HAVE_THREADS 307 static void *aubio_sampler_openfn(void *z) { 308 aubio_sampler_t *p = z; 309 uint_t err; 310 int oldtype; 311 void *ret; 312 pthread_setcancelstate(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); 313 pthread_mutex_lock(&p->open_mutex); 314 p->open_thread_running = 1; 315 err = aubio_sampler_load(p, p->next_uri); 316 p->open_thread_running = 0; 317 pthread_mutex_unlock(&p->open_mutex); 318 ret = &err; 319 pthread_exit(ret); 320 } 321 #endif 322 323 uint_t 324 aubio_sampler_queue(aubio_sampler_t *o, const char_t *uri) 325 { 326 #ifdef HAVE_THREADS 327 uint_t ret = AUBIO_OK; 328 329 if (o->reading_from == aubio_sampler_reading_from_table) { 330 o->reading_from = aubio_sampler_reading_from_source; 331 o->opened = 0; 332 o->finished = 1; 333 } 334 /* open uri in open_thread */ 335 if (o->open_thread_running) { 336 // cancel previous open_thread 337 if (pthread_cancel(o->open_thread)) { 338 AUBIO_WRN("sampler: failed queuing %s (cancelling existing open thread failed)\n", uri); 339 return AUBIO_FAIL; 340 } else { 341 AUBIO_WRN("sampler: cancelled queuing %s (queuing %s now)\n", 342 o->next_uri, uri); 343 } 344 o->open_thread_running = 0; 345 } 346 void *threadret; 347 if (o->open_thread && pthread_join(o->open_thread, &threadret)) { 348 AUBIO_WRN("sampler: joining thread failed\n"); 349 } 350 if (pthread_mutex_trylock(&o->open_mutex)) { 351 AUBIO_WRN("sampler: failed queuing %s (locking failed)\n", uri); 352 ret = AUBIO_FAIL; 353 goto lock_failed; 354 } 355 o->opened = 0; // while opening 356 o->started = 0; 357 o->available = 0; 358 if (o->next_uri) AUBIO_FREE(o->next_uri); 359 o->next_uri = AUBIO_ARRAY(char_t, strnlen(uri, PATH_MAX) + 1); 360 strncpy(o->next_uri, uri, strnlen(uri, PATH_MAX) + 1); 361 o->waited = 0; 362 if (pthread_create(&o->open_thread, 0, aubio_sampler_openfn, o) != 0) { 363 AUBIO_ERR("sampler: failed creating opening thread\n"); 364 ret = AUBIO_FAIL; 365 goto thread_create_failed; 366 } 367 368 thread_create_failed: 369 pthread_mutex_unlock(&o->open_mutex); 370 lock_failed: 371 if (ret == AUBIO_OK) { 372 //AUBIO_WRN("sampler: queued %s\n", uri); 373 } else { 374 AUBIO_ERR("sampler: queueing %s failed\n", uri); 375 } 376 return ret; 377 #else 378 AUBIO_WRN("sampler: opening %s, not queueing (not compiled with threading)\n", uri); 379 return aubio_sampler_load(o, uri); 380 #endif 381 } 382 383 #ifdef HAVE_THREADS 384 385 uint_t aubio_sampler_reading_from_source_ring_fetch(aubio_sampler_t*s); 386 387 void *aubio_sampler_readfn(void *z) { 388 aubio_sampler_t *p = z; 389 while(1) { 390 pthread_mutex_lock(&p->read_mutex); 391 if (p->open_thread_running) { 392 //AUBIO_WRN("sampler: readfn(): file is being opened\n"); 393 pthread_cond_signal(&p->read_avail); 394 //pthread_cond_wait(&p->read_request, &p->read_mutex); 395 } else if (p->opened && !p->started && !p->finished) { 396 //AUBIO_WRN("sampler: readfn(): file started\n"); 397 if (p->ring) { 398 p->available = aubio_sampler_reading_from_source_ring_fetch(p); 399 } else { 400 p->available = aubio_sampler_pull_from_source(p); 401 if (p->available < (sint_t)p->source_blocksize) 402 aubio_sampler_do_eof(p); 403 } 404 pthread_cond_signal(&p->read_avail); 405 if (!p->finished) { 406 pthread_cond_wait(&p->read_request, &p->read_mutex); 407 } 408 } else { 409 //AUBIO_WRN("sampler: readfn(): idle?\n"); 410 pthread_cond_signal(&p->read_avail); 411 pthread_cond_wait(&p->read_request, &p->read_mutex); 412 if (p->read_thread_finish) { 413 goto done; 414 } 415 } 416 pthread_mutex_unlock(&p->read_mutex); 417 } 418 done: 419 //AUBIO_WRN("sampler: exiting reading thread\n"); 420 pthread_mutex_unlock(&p->read_mutex); 421 pthread_exit(NULL); 422 } 423 #endif 424 425 void 426 aubio_sampler_read(aubio_sampler_t *s, fvec_t *output, uint_t *read) { 427 if (s->reading_from == aubio_sampler_reading_from_source) { 428 aubio_sampler_read_from_source(s, output, read); 429 } else if (s->reading_from == aubio_sampler_reading_from_table) { 430 aubio_sampler_read_from_table(s, output, read); 431 } 432 } 433 434 static void 435 aubio_sampler_reading_from_source_naive(aubio_sampler_t *s, fvec_t * output, 436 uint_t *read) 437 { 438 // directly read from disk 439 //aubio_source_do(s->source, output, read); 440 s->source_output = output; 441 *read = aubio_sampler_pull_from_source(s); 442 if (*read < s->source_blocksize) { 443 //AUBIO_WRN("sampler: calling go_eof in _read_from_source()\n"); 444 aubio_sampler_do_eof(s); 445 } 446 } 447 448 uint_t 449 aubio_sampler_reading_from_source_ring_fetch(aubio_sampler_t*s) { 450 // read source_blocksize (> blocksize) at once 451 int ring_avail = aubio_ringbuffer_get_available(s->ring); 452 //if (ring_avail < s->blocksize) { 453 uint_t available = 0; 454 if (ring_avail < (sint_t)s->blocksize) { 455 available = aubio_sampler_pull_from_source(s); 456 if (available > 0) { 457 aubio_ringbuffer_push(s->ring, s->source_output, available); 458 } 459 if (available < s->blocksize) { 460 //AUBIO_WRN("sampler: short read %d\n", available); 461 if (ring_avail + available <= s->blocksize) { 462 s->eof_remaining = available + ring_avail; 463 if (s->eof_remaining == 0) s->eof_remaining = s->blocksize; 464 ring_avail = aubio_ringbuffer_get_available(s->ring); 465 //AUBIO_ERR("sampler: eof in: %d, last fetch: %d, in ring: %d\n", 466 // s->eof_remaining, available, ring_avail); 467 if (s->loop) { 468 aubio_sampler_seek(s,0); 469 // read some frames from beginning of source for perfect looping 470 if (s->perfectloop) { 471 available = aubio_sampler_pull_from_source(s); 472 if (available <= 0) { 473 AUBIO_ERR("sampler: perfectloop but s->available = 0 !\n"); 474 } else { 475 aubio_ringbuffer_push(s->ring, s->source_output, available); 476 } 477 } 478 } 479 } 480 } 481 } 482 return available; 483 } 484 485 static void 486 aubio_sampler_reading_from_source_ring_pull(aubio_sampler_t *s, fvec_t *output, 487 uint_t *read) 488 { 489 // write into output 490 int ring_avail = aubio_ringbuffer_get_available(s->ring); 491 if (ring_avail >= (sint_t)s->blocksize) { 492 //AUBIO_MSG("sampler: pulling %d / %d from ringbuffer\n", s->blocksize, ring_avail); 493 aubio_ringbuffer_pull(s->ring, output, s->blocksize); 494 *read = s->blocksize; 495 if (s->eof_remaining > 0) { 496 if (s->eof_remaining <= s->blocksize) { 497 //AUBIO_WRN("sampler: signaling eof\n"); 498 s->eof = 1; // signal eof 499 s->eof_remaining = 0; 500 } else if (s->eof_remaining <= s->source_blocksize) { 501 s->eof_remaining -= s->blocksize; 502 } 503 } 504 } else { 505 //AUBIO_MSG("sampler: last frame, pulling remaining %d left\n", ring_avail); 506 *read = 0; 507 if (ring_avail > 0) { 508 // pull remaining frames in ring buffer 509 aubio_ringbuffer_pull(s->ring, output, ring_avail); 510 *read += ring_avail; 511 } 512 // signal eof 513 aubio_sampler_do_eof(s); 514 // finished playing, reset ringbuffer for next read 515 if (!s->playing) 516 aubio_ringbuffer_reset(s->ring); 517 } 518 } 519 520 static void 521 aubio_sampler_reading_from_source_ring(aubio_sampler_t *s, fvec_t *output, 522 uint_t *read) 523 { 524 #if 0 525 aubio_sampler_reading_from_source_ring_fetch(s); 526 aubio_sampler_reading_from_source_ring_pull(s, output, read); 527 #else // raw version 528 uint_t source_read; 529 while (aubio_timestretch_get_available(s->ts) < (sint_t)s->blocksize 530 && s->eof_remaining == 0) { 531 aubio_source_do(s->source, s->source_output, &source_read); 532 aubio_timestretch_push(s->ts, s->source_output, source_read); 533 if (source_read < s->source_output->length) s->eof_remaining = source_read; 534 //AUBIO_WRN("sampler: pushed %d, now %d available\n", 535 // source_read, aubio_timestretch_get_available(s->ts)); 536 } 537 aubio_timestretch_do(s->ts, output, read); 538 if (s->eof_remaining > s->blocksize) { 539 s->eof_remaining -= s->blocksize; 540 } 541 if (*read < output->length) { 542 //AUBIO_WRN("sampler: short read %d, eof at %d\n", *read, s->eof_remaining); 543 s->eof_remaining = 0; 544 aubio_timestretch_reset(s->ts); 545 aubio_sampler_do_eof(s); 546 if (s->loop && s->perfectloop) { 547 uint_t partialread; 548 fvec_t tmpout; tmpout.data = output->data + *read; 549 tmpout.length = output->length - *read; 550 while (aubio_timestretch_get_available(s->ts) < (sint_t)tmpout.length 551 && s->eof_remaining == 0) { 552 aubio_source_do(s->source, s->source_output, &source_read); 553 aubio_timestretch_push(s->ts, s->source_output, source_read); 554 if (source_read < s->source_output->length) s->eof_remaining = source_read; 555 } 556 aubio_timestretch_do(s->ts, &tmpout, &partialread); 557 //AUBIO_WRN("sampler: partial read %d + %d\n", *read, partialread); 558 *read += partialread; 559 } 560 } 561 #endif 562 } 563 564 #ifdef HAVE_THREADS 565 static void 566 aubio_sampler_read_from_source_threaded(aubio_sampler_t *s, fvec_t *output, 567 uint_t *read) { 568 // request at least output->length 569 // make sure we have enough samples read from source 570 int available; 571 pthread_mutex_lock(&s->read_mutex); 572 if (!s->opened || s->open_thread_running) { 573 //AUBIO_ERR("sampler: _read_from_source: not opened, signaling read_request\n"); 574 pthread_cond_signal(&s->read_request); 575 available = 0; 576 } else if (!s->finished) { 577 pthread_cond_signal(&s->read_request); 578 pthread_cond_wait(&s->read_avail, &s->read_mutex); 579 //AUBIO_ERR("sampler: _read_from_source: %d\n", s->available); 580 available = s->available; 581 } else { 582 //AUBIO_WRN("sampler: _read_from_source: eof\n"); 583 pthread_cond_signal(&s->read_request); 584 available = 0; 585 } 586 pthread_mutex_unlock(&s->read_mutex); 587 //AUBIO_WRN("sampler: got %d available in _read_from_source\n", available); 588 // read -> number of samples read 589 if (!s->perfectloop && s->source_blocksize == s->blocksize) { 590 if (available >= (sint_t)s->blocksize) { 591 fvec_copy(s->source_output, output); 592 *read = s->blocksize; 593 } else if (available > 0) { 594 fvec_copy(s->source_output, output); 595 *read = available; 596 } else { 597 fvec_zeros(output); 598 *read = 0; 599 } 600 } else { 601 aubio_sampler_reading_from_source_ring_pull(s, output, read); 602 } 603 } 604 #endif 605 606 void 607 aubio_sampler_read_from_source(aubio_sampler_t *s, fvec_t *output, uint_t *read) { 608 #ifdef HAVE_THREADS 609 if (s->threaded_read) { // if threaded 610 aubio_sampler_read_from_source_threaded(s, output, read); 611 } else 612 #endif 613 { 614 if (s->finished) { 615 *read = 0; 616 } 617 else if (s->source_blocksize == s->blocksize && !s->perfectloop) { 618 aubio_sampler_reading_from_source_naive(s, output, read); 619 } else { 620 aubio_sampler_reading_from_source_ring(s, output, read); 621 } 622 #if 1 623 if (s->loop && s->perfectloop && *read != s->blocksize) { // && s->started && !s->finished) { 624 AUBIO_ERR("sampler: perfectloop but read only %d\n", *read); 625 } 626 #endif 627 } 628 } 629 630 void 631 aubio_sampler_read_from_table(aubio_sampler_t *s, fvec_t *output, uint_t *read) { 632 *read = 0; 633 if (s->table == NULL) { 634 AUBIO_WRN("sampler: _pull_from_table but table not set %d, %d\n", 635 output->length, *read); 636 } else if (s->playing) { 637 #if 0 638 uint_t available = s->table->length - s->table_index; 639 fvec_t tmp; 640 tmp.data = s->table->data + s->table_index; 641 if (available < s->blocksize) { 642 //AUBIO_WRN("sampler: _pull_from_table: table length %d, index: %d, read %d\n", 643 // s->table->length, s->table_index, *read); 644 tmp.length = available; 645 fvec_t tmpout; tmpout.data = output->data; tmpout.length = available; 646 fvec_copy(&tmp, &tmpout); 647 if (s->loop && s->perfectloop) { 648 uint_t remaining = s->blocksize - available; 649 tmpout.data = output->data + available; tmpout.length = remaining; 650 tmp.data = s->table->data; tmp.length = remaining; 651 fvec_copy(&tmp, &tmpout); 652 s->table_index = remaining; 653 *read = s->blocksize; 654 } else { 655 s->table_index = 0; 656 *read = available; 657 } 658 aubio_sampler_do_eof(s); 659 } else { 660 tmp.length = s->blocksize; 661 fvec_copy(&tmp, output); 662 s->table_index += output->length; 663 *read = s->blocksize; 664 } 665 #else 666 fvec_t tmp, tmpout; 667 uint_t source_read = 0; 668 while (aubio_timestretch_get_available(s->ts) < (sint_t)s->blocksize 669 && s->eof_remaining == 0) { 670 uint_t available = s->table->length - s->table_index; 671 if (available < s->source_blocksize) { 672 source_read = available; 673 } else { 674 source_read = s->source_blocksize; 675 } 676 tmp.length = source_read; tmp.data = s->table->data + s->table_index; 677 tmpout.data = s->source_output->data; tmpout.length = source_read; 678 fvec_copy(&tmp, &tmpout); 679 aubio_timestretch_push(s->ts, &tmpout, source_read); 680 if (source_read < s->source_blocksize) { 681 s->eof_remaining = source_read; 682 s->table_index = s->source_blocksize - *read; 683 } else { 684 s->table_index += source_read; 685 } 686 if (s->table_index == s->table->length) s->table_index = 0; 687 //AUBIO_WRN("sampler: pushed %d, now %d available, table_index %d, eof %d\n", 688 // source_read, aubio_timestretch_get_available(s->ts), 689 // s->table_index, s->eof_remaining); 690 } 691 aubio_timestretch_do(s->ts, output, read); 692 if (*read == 0) { 693 //AUBIO_WRN("sampler: pushed %d, now %d available, table_index %d\n", 694 // *read, aubio_timestretch_get_available(s->ts), s->table_index); 695 } 696 if (s->eof_remaining > s->blocksize) { 697 s->eof_remaining -= s->blocksize; 698 } 699 if (*read < output->length) { 700 s->eof_remaining = 0; 701 aubio_sampler_do_eof(s); 702 } 703 #if 0 704 if (*read < output->length) { 705 //uint_t available = aubio_timestretch_get_available(s->ts); 706 s->eof_remaining = 0; 707 aubio_timestretch_reset(s->ts); 708 aubio_sampler_do_eof(s); 709 } 710 #endif 711 #if 0 712 if (*read < output->length) { 713 //uint_t available = aubio_timestretch_get_available(s->ts); 714 s->eof_remaining = 0; 715 aubio_timestretch_reset(s->ts); 716 aubio_sampler_do_eof(s); 717 if (s->loop && s->perfectloop) { 718 tmpout.data = output->data + *read; 719 tmpout.length = output->length - *read; 720 while (aubio_timestretch_get_available(s->ts) < (sint_t)tmpout.length 721 && s->eof_remaining == 0) { 722 uint_t available = s->table->length - s->table_index; 723 if (available < s->source_blocksize) { 724 source_read = available; 725 } else { 726 source_read = s->source_blocksize; 727 } 728 //AUBIO_WRN("sampler: short read %d, remaining %d\n", *read, remaining); 729 tmp.length = source_read; tmp.data = s->table->data + s->table_index; 730 fvec_t tmpout2; tmpout2.data = s->source_output->data; tmpout2.length = source_read; 731 fvec_copy(&tmp, &tmpout2); 732 aubio_timestretch_push(s->ts, &tmpout2, source_read); 733 if (source_read < s->source_blocksize) { 734 s->eof_remaining = source_read; 735 s->table_index = 0; 736 } else { 737 s->table_index += source_read; 738 } 739 if (s->table_index == s->table->length) s->table_index = 0; 740 //AUBIO_WRN("sampler: second push, pushed %d, now %d available\n", 741 // source_read, aubio_timestretch_get_available(s->ts)); 742 } 743 uint_t partialread; 744 aubio_timestretch_do(s->ts, &tmpout, &partialread); 745 AUBIO_WRN("sampler: partial read %d + %d\n", *read, partialread); 746 *read += partialread; 747 //s->eof = 1; 748 } 749 } 750 #endif 751 752 #endif 753 } 754 } 755 756 uint_t 757 aubio_sampler_set_table(aubio_sampler_t *s, fvec_t *samples) { 758 if (!samples || !s) return AUBIO_FAIL; 759 if (s->reading_from == aubio_sampler_reading_from_source) { 760 //aubio_sampler_close_reading_thread(s); 761 } 762 s->table = samples; 763 //AUBIO_INF("sampler: setting table (%d long)\n", s->table->length); 764 s->table_index = 0; 765 s->reading_from = aubio_sampler_reading_from_table; 766 //s->threaded_read = 0; 767 s->opened = 1; 768 s->finished = 1; 769 return AUBIO_OK; 770 } 771 772 sint_t 773 aubio_sampler_pull_from_source(aubio_sampler_t *s) 774 { 775 // pull source_blocksize samples from source, return available frames 776 uint_t source_read = s->source_blocksize; 777 if (s->source == NULL) { 778 AUBIO_ERR("sampler: trying to fetch on NULL source\n"); 779 return -1; 780 } 781 #if 1 782 aubio_source_do(s->source, s->source_output, &source_read); 783 return source_read; 784 #else 785 uint_t source_read_tmp; 786 while (aubio_timestretch_get_available(s->ts) < (sint_t)s->blocksize 787 && s->last_read == 0) { 788 aubio_source_do(s->source, s->source_output_tmp, &source_read_tmp); 789 aubio_timestretch_push(s->ts, s->source_output_tmp, source_read_tmp); 790 if (source_read_tmp < s->source_output_tmp->length) s->last_read = source_read; 791 } 792 aubio_timestretch_do(s->ts, s->source_output, &source_read); 793 if (s->last_read > s->blocksize) { 794 s->last_read -= s->blocksize; 795 } 796 if (source_read < s->source_blocksize) { 797 s->last_read = 0; 798 //AUBIO_ERR("sampler: calling timestretch reset %d %d\n", source_read, s->source_blocksize); 799 aubio_timestretch_reset(s->ts); 800 } 801 return source_read; 802 #endif 803 } 804 805 806 uint_t 807 aubio_sampler_get_samplerate (aubio_sampler_t *o) 808 { 809 return o->samplerate; 810 } 811 812 uint_t 813 aubio_sampler_get_opened (aubio_sampler_t *o) 814 { 815 return o->opened; //== 1 ? AUBIO_OK : AUBIO_FAIL; 816 } 817 818 uint_t 819 aubio_sampler_get_finished(aubio_sampler_t *o) 820 { 821 return o->finished; 822 } 823 824 uint_t 825 aubio_sampler_get_eof (aubio_sampler_t *o) 826 { 827 return o->eof; 828 } 829 830 uint_t 831 #ifdef HAVE_THREADS 832 aubio_sampler_get_waited_opening (aubio_sampler_t *o, uint_t waited) { 74 833 if (o->playing) { 75 aubio_source_do (o->source, o->source_output, &read); 76 for (i = 0; i < output->length; i++) { 77 output->data[i] += o->source_output->data[i]; 78 } 79 if (read < o->blocksize) o->playing = 0; 80 } 81 if (input && input != output) { 82 for (i = 0; i < output->length; i++) { 83 output->data[i] += input->data[i]; 84 } 85 } 86 } 87 88 void aubio_sampler_do_multi ( aubio_sampler_t * o, const fmat_t * input, fmat_t * output) 89 { 90 uint_t read = 0, i, j; 91 if (o->playing) { 92 aubio_source_do_multi (o->source, o->source_output_multi, &read); 93 for (i = 0; i < output->height; i++) { 94 for (j = 0; j < output->length; j++) { 95 output->data[i][j] += o->source_output_multi->data[i][j]; 96 } 97 } 98 if ( read < o->blocksize ) o->playing = 0; 99 } 100 if (input && input != output) { 101 for (i = 0; i < output->height; i++) { 102 for (j = 0; j < output->length; j++) { 103 output->data[i][j] += input->data[i][j]; 104 } 105 } 834 if (!o->opened) { 835 o->waited += waited; 836 } else if (o->waited) { 837 //AUBIO_WRN("sampler: waited %d frames (%.2fms) while opening %s\n", 838 // o->waited, 1000.*o->waited/(smpl_t)o->samplerate, o->uri); 839 uint_t waited = o->waited; 840 o->waited = 0; 841 return waited; 842 } 843 } 844 #else 845 aubio_sampler_get_waited_opening (aubio_sampler_t *o UNUSED, uint_t waited UNUSED) { 846 #endif 847 return 0; 848 } 849 850 uint_t 851 aubio_sampler_seek(aubio_sampler_t * o, uint_t pos) 852 { 853 //AUBIO_WRN("sampler: seeking to 0\n"); 854 uint_t ret = AUBIO_FAIL; 855 o->finished = 0; 856 if (!o->opened) return AUBIO_OK; 857 if (o->source) { 858 ret = aubio_source_seek(o->source, pos); 859 } else if (o->table && (sint_t)pos >= 0 && pos < o->table->length) { 860 o->table_index = pos < o->table->length ? pos : o->table->length - 1; 861 ret = AUBIO_OK; 862 } 863 //o->last_read = 0; 864 return ret; 865 } 866 867 void 868 aubio_sampler_do_eof (aubio_sampler_t * o) 869 { 870 //AUBIO_MSG("sampler: calling _do_eof()\n"); 871 o->finished = 1; 872 o->eof = 1; 873 if (!o->loop) { 874 o->playing = 0; 875 } else { 876 if (o->reading_from == aubio_sampler_reading_from_source) 877 aubio_sampler_seek(o, 0); 878 //o->finished = 0; 879 } 880 } 881 882 void aubio_sampler_do ( aubio_sampler_t * o, fvec_t * output, uint_t *read) 883 { 884 o->eof = 0; 885 if (o->opened == 1 && o->playing) { 886 aubio_sampler_read(o, output, read); 887 } else { 888 fvec_zeros(output); 889 *read = 0; 890 } 891 } 892 893 void aubio_sampler_do_multi ( aubio_sampler_t * o, fmat_t * output, uint_t *read) 894 { 895 o->eof = 0; 896 if (o->opened == 1 && o->playing) { 897 //aubio_sampler_read_multi(o, output, read); 898 } else { 899 fmat_zeros(output); 900 *read = 0; 106 901 } 107 902 } … … 118 913 } 119 914 915 uint_t aubio_sampler_get_loop ( aubio_sampler_t * o ) 916 { 917 return o->loop; 918 } 919 920 uint_t aubio_sampler_set_loop ( aubio_sampler_t * o, uint_t loop ) 921 { 922 o->loop = (loop == 1) ? 1 : 0; 923 return 0; 924 } 925 120 926 uint_t aubio_sampler_play ( aubio_sampler_t * o ) 121 927 { 122 aubio_source_seek (o->source, 0);123 928 return aubio_sampler_set_playing (o, 1); 124 929 } … … 129 934 } 130 935 936 uint_t aubio_sampler_loop ( aubio_sampler_t * o ) 937 { 938 aubio_sampler_set_loop(o, 1); 939 aubio_sampler_seek(o, 0); 940 return aubio_sampler_set_playing (o, 1); 941 } 942 943 uint_t aubio_sampler_trigger ( aubio_sampler_t * o ) 944 { 945 if (o->ring) aubio_ringbuffer_reset(o->ring); 946 aubio_sampler_set_loop(o, 0); 947 aubio_sampler_seek(o, 0); 948 return aubio_sampler_set_playing (o, 1); 949 } 950 951 uint_t aubio_sampler_set_perfectloop (aubio_sampler_t *s, uint_t perfectloop) { 952 if (!s) return AUBIO_FAIL; 953 s->perfectloop = perfectloop; 954 return AUBIO_OK; 955 } 956 957 uint_t aubio_sampler_get_perfectloop (aubio_sampler_t *s) { 958 if (!s) return AUBIO_FAIL; 959 return s->perfectloop; 960 } 961 962 963 uint_t aubio_sampler_set_stretch(aubio_sampler_t *s, smpl_t stretch) 964 { 965 if (!s->ts) return AUBIO_FAIL; 966 return aubio_timestretch_set_stretch(s->ts, stretch); 967 } 968 969 smpl_t aubio_sampler_get_stretch(aubio_sampler_t *s) 970 { 971 if (!s->ts) return 1.; 972 return aubio_timestretch_get_stretch(s->ts); 973 } 974 975 uint_t aubio_sampler_set_transpose(aubio_sampler_t *s, smpl_t transpose) 976 { 977 if (!s->ts) return AUBIO_FAIL; 978 return aubio_timestretch_set_transpose(s->ts, transpose); 979 } 980 981 smpl_t aubio_sampler_get_transpose(aubio_sampler_t *s) 982 { 983 if (!s->ts) return 0.; 984 return aubio_timestretch_get_transpose(s->ts); 985 } 986 987 131 988 void del_aubio_sampler( aubio_sampler_t * o ) 132 989 { 990 #ifdef HAVE_THREADS 991 // close opening thread 992 aubio_sampler_close_opening_thread(o); 993 // close reading thread 994 aubio_sampler_close_reading_thread(o); 995 #endif 996 //if (o->source_output) { 997 if (o->source_output && (o->threaded_read || o->perfectloop)) { 998 del_fvec(o->source_output); 999 } 1000 if (o->source_moutput) { 1001 del_fmat(o->source_moutput); 1002 } 1003 if (o->ring) { 1004 del_aubio_ringbuffer(o->ring); 1005 } 1006 if (o->ts) { 1007 del_aubio_timestretch(o->ts); 1008 } 133 1009 if (o->source) { 134 1010 del_aubio_source(o->source); 135 1011 } 136 if (o->uri) AUBIO_FREE(o->uri);137 del_fvec(o->source_output);138 del_fmat(o->source_output_multi);139 1012 AUBIO_FREE(o); 140 1013 } -
src/synth/sampler.h
rb762f8d rb201912 24 24 /** \file 25 25 26 Load and play sound files.26 Load and play a sound file. 27 27 28 28 This file loads a sample and gets ready to play it. … … 30 30 The `_do` function adds the new samples to the input, and write the result as 31 31 the output. 32 33 TODO: 34 - add _preset_threaded(level) 35 - rename _set_loop/_get_loop to _set_looping/_get_looping 36 - add option to pass a callback to signal eof 32 37 33 38 \example synth/test-sampler.c … … 50 55 51 56 */ 52 aubio_sampler_t * new_aubio_sampler(uint_t samplerate, uint_t hop_size);57 aubio_sampler_t * new_aubio_sampler(uint_t hop_size, uint_t samplerate); 53 58 54 59 /** load source in sampler … … 59 64 \return 0 if successful, non-zero otherwise 60 65 66 This function attempts to load a new source, swaps the current one with the 67 newly loaded one (or NULL if loading failed), then delete the old one. 68 61 69 */ 62 70 uint_t aubio_sampler_load( aubio_sampler_t * o, const char_t * uri ); 63 71 72 /** queue source in sampler 73 74 \param o sampler, created by new_aubio_sampler() 75 \param uri the uri of the source to load 76 77 \return 0 if successfully queued, non-zero otherwise 78 79 This function is identical to aubio_sampler_load(), except it will be called 80 in its own thread to avoid blocking calls to aubio_sampler_do(). 81 82 */ 83 uint_t aubio_sampler_queue(aubio_sampler_t * o, const char_t * uri ); 84 85 /** set array to read from 86 87 \param o sampler, created by new_aubio_sampler() 88 \param samples the vector to set the table to 89 90 \return 0 if successfully set, non-zero otherwise 91 92 */ 93 uint_t aubio_sampler_set_table(aubio_sampler_t *o, fvec_t *samples); 94 64 95 /** process sampler function 65 96 66 97 \param o sampler, created by new_aubio_sampler() 67 \param input input of the sampler, to be added to the output68 98 \param output output of the sampler 69 70 This function adds the new samples from the playing source to the output. 71 72 If `input` is not NULL and different from `output`, then the samples from `input` 73 are added to the output.74 75 */ 76 void aubio_sampler_do ( aubio_sampler_t * o, const fvec_t * input, fvec_t * output);99 \param read will be set to then number of samples actually read 100 101 This function get new samples from the sampler and store them into output. 102 103 The output vector will be completed with 0 if too few samples are available. 104 105 */ 106 void aubio_sampler_do ( aubio_sampler_t * o, fvec_t * output, uint_t *read); 77 107 78 108 /** process sampler function, multiple channels 79 109 80 110 \param o sampler, created by new_aubio_sampler() 81 \param input input of the sampler, to be added to the output82 111 \param output output of the sampler 83 84 This function adds the new samples from the playing source to the output. 85 86 If `input` is not NULL and different from `output`, then the samples from `input` 87 are added to the output. 88 89 */ 90 void aubio_sampler_do_multi ( aubio_sampler_t * o, const fmat_t * input, fmat_t * output); 112 \param read will be set to the number of samples actually read 113 114 This function is identical to aubio_sampler_do(), but for a multi-channel source. 115 116 */ 117 void aubio_sampler_do_multi ( aubio_sampler_t * o, fmat_t * output, uint_t *read); 91 118 92 119 /** get current playing state … … 109 136 uint_t aubio_sampler_set_playing ( aubio_sampler_t * o, uint_t playing ); 110 137 111 /** play sample from start 138 /** get current looping state 139 140 \param o sampler, created by new_aubio_sampler() 141 142 \return 0 if not looping , 1 if looping 143 144 */ 145 uint_t aubio_sampler_get_loop(aubio_sampler_t * o); 146 147 /** set current looping state 148 149 \param o sampler, created by new_aubio_sampler() 150 \param loop 0 for not looping, 1 for looping 151 152 \return 0 if successful, 1 otherwise 153 154 */ 155 uint_t aubio_sampler_set_loop(aubio_sampler_t * o, uint_t loop); 156 157 /** play sample 112 158 113 159 \param o sampler, created by new_aubio_sampler() … … 118 164 uint_t aubio_sampler_play ( aubio_sampler_t * o ); 119 165 166 /** play sample from start, looping it 167 168 \param o sampler, created by new_aubio_sampler() 169 170 \return 0 if successful, 1 otherwise 171 172 */ 173 uint_t aubio_sampler_loop ( aubio_sampler_t * o ); 174 175 /** play sample from start, once 176 177 \param o sampler, created by new_aubio_sampler() 178 179 \return 0 if successful, 1 otherwise 180 181 */ 182 uint_t aubio_sampler_trigger ( aubio_sampler_t * o ); 183 120 184 /** stop sample 121 185 … … 126 190 */ 127 191 uint_t aubio_sampler_stop ( aubio_sampler_t * o ); 192 193 /** get end-of-file status 194 195 \param o sampler, created by new_aubio_sampler() 196 197 \return 1 when the eof is being reached, 0 otherwise 198 199 */ 200 uint_t aubio_sampler_get_eof(aubio_sampler_t * o); 201 202 /** get end-of-file status 203 204 \param o sampler, created by new_aubio_sampler() 205 206 \return 1 when end of file has been reached, 0 otherwise 207 208 */ 209 uint_t aubio_sampler_get_finished (aubio_sampler_t * o); 210 211 /** get samplerate 212 213 \param o sampler, created by new_aubio_sampler() 214 215 \return samplerate of the sampler 216 217 */ 218 uint_t aubio_sampler_get_samplerate(aubio_sampler_t * o); 219 220 /** get the number of samples that were set to zero while opening a file 221 222 \param o sampler, created by new_aubio_sampler() 223 \param waited the number of frames processed during this block 224 225 \return the total delay in samples when the file was successfuly opened, 0 226 otherwise 227 228 */ 229 uint_t aubio_sampler_get_waited_opening(aubio_sampler_t * o, uint_t waited); 230 231 /** get current time stretching factor 232 233 \param o sampler, created by new_aubio_sampler() 234 235 \return the current time stretch factor 236 237 */ 238 smpl_t aubio_sampler_get_stretch (aubio_sampler_t *o); 239 240 /** set current time stretching factor 241 242 \param o sampler, created by new_aubio_sampler() 243 \param stretch new time stretching factor 244 245 \return AUBIO_OK on success, AUBIO_FAIL otherwise 246 247 */ 248 uint_t aubio_sampler_set_stretch (aubio_sampler_t *o, smpl_t stretch); 249 250 /** get current pitch shifting factor 251 252 \param o sampler, created by new_aubio_sampler() 253 254 \return the current pitch transposition factor 255 256 */ 257 smpl_t aubio_sampler_get_transpose (aubio_sampler_t *o); 258 259 /** set current pitch shifting factor 260 261 \param o sampler, created by new_aubio_sampler() 262 \param transpose new pitch shifting (transposition) factor 263 264 \return AUBIO_OK on success, AUBIO_FAIL otherwise 265 266 */ 267 uint_t aubio_sampler_set_transpose (aubio_sampler_t *o, smpl_t transpose); 268 269 /** get the current perfect loop mode 270 271 \param o sampler, created by new_aubio_sampler() 272 273 \return the total delay in samples when the file was successfuly opened, 0 274 otherwise 275 276 */ 277 uint_t aubio_sampler_get_perfectloop (aubio_sampler_t *o); 278 279 /** set the perfect loop mode 280 281 \param o sampler, created by new_aubio_sampler() 282 \param perfectloop 1 to set perfect loop mode, 0 to turn it of 283 284 \return AUBIO_OK on success, AUBIO_FAIL otherwise 285 286 */ 287 uint_t aubio_sampler_set_perfectloop (aubio_sampler_t *o, uint_t perfectloop); 288 289 /** seek to position 290 291 \param o sampler, created by new_aubio_sampler() 292 \param pos position to seek to, in samples 293 294 \return 0 if successful, 1 otherwise 295 296 */ 297 uint_t aubio_sampler_seek(aubio_sampler_t * o, uint_t pos); 128 298 129 299 /** destroy ::aubio_sampler_t object -
src/wscript_build
rb762f8d rb201912 6 6 uselib += ['SAMPLERATE'] 7 7 uselib += ['SNDFILE'] 8 uselib += ['RUBBERBAND'] 8 9 uselib += ['AVCODEC'] 9 10 uselib += ['AVFORMAT'] … … 12 13 uselib += ['AVUTIL'] 13 14 uselib += ['BLAS'] 15 uselib += ['PTHREAD'] 14 16 15 17 source = ctx.path.ant_glob('*.c **/*.c') -
tests/src/synth/test-sampler.c
rb762f8d rb201912 1 1 #include <aubio.h> 2 2 #include "utils_tests.h" 3 4 int time_was_reached (smpl_t time_s, uint_t n_frames, uint_t hop_size, uint_t samplerate) { 5 if ((n_frames / hop_size) == (uint_t)(time_s * samplerate) / hop_size) { 6 PRINT_MSG("reached %.2f sec at %d samples\n", time_s, n_frames); 7 return 1; 8 } else { 9 return 0; 10 } 11 } 3 12 4 13 int main (int argc, char **argv) … … 6 15 sint_t err = 0; 7 16 8 if (argc < 4) {17 if (argc < 2) { 9 18 err = 2; 10 19 PRINT_ERR("not enough arguments\n"); 11 PRINT_MSG("usage: %s < input_path> <output_path> <sample_path> [samplerate]\n", argv[0]);20 PRINT_MSG("usage: %s <sample_path> [samplerate] [blocksize] [output_path]\n", argv[0]); 12 21 return err; 13 22 } 14 23 15 uint_t samplerate = 0; // default is the samplerate of input_path 16 uint_t hop_size = 256; 17 uint_t n_frames = 0, read = 0; 24 uint_t samplerate = 44100; // default is 44100 25 uint_t hop_size = 64; //256; 26 uint_t n_frames = 0, frames_played = 0; 27 uint_t read = 0; 28 char_t *sink_path = NULL; 29 aubio_sink_t *sink = NULL; 18 30 19 char_t *s ource_path = argv[1];20 char_t *sink_path = argv[2];21 char_t *sample_path = argv[3];22 if ( argc == 5 ) samplerate = atoi(argv[4]);31 char_t *sample_path = argv[1]; 32 if ( argc > 2 ) samplerate = atoi(argv[2]); 33 if ( argc > 3 ) hop_size = atoi(argv[3]); 34 if ( argc > 4 ) sink_path = argv[4]; 23 35 24 36 fvec_t *vec = new_fvec(hop_size); 25 aubio_source_t *source = new_aubio_source(source_path, samplerate, hop_size);26 if (samplerate == 0 ) samplerate = aubio_source_get_samplerate(source);27 aubio_sink_t *sink = new_aubio_sink(sink_path, samplerate);28 37 29 aubio_sampler_t * sampler = new_aubio_sampler (samplerate, hop_size); 38 aubio_sampler_t * sampler = new_aubio_sampler (hop_size, samplerate); 39 if (!vec) goto beach; 40 if (!sampler) goto beach_sampler; 41 // load source file 42 aubio_sampler_load (sampler, sample_path); 43 // load source file (asynchronously) 44 //aubio_sampler_queue (sampler, sample_path); 45 samplerate = aubio_sampler_get_samplerate (sampler); 46 if (samplerate == 0) { 47 PRINT_ERR("starting with samplerate = 0\n"); 48 //goto beach_sink; 49 } 30 50 31 aubio_sampler_load (sampler, sample_path); 51 if (sink_path) { 52 sink = new_aubio_sink(sink_path, samplerate); 53 if (!sink) goto beach_sink; 54 } 55 56 smpl_t sample_duration = 2.953; 57 uint_t sample_repeat = 10; 58 smpl_t t1 = 1., 59 t2 = t1 + sample_duration * sample_repeat - .1, 60 t3 = t2 - sample_duration + .1, 61 t4 = t3 + sample_duration + .1, 62 t5 = t4 + sample_duration + .1, 63 total_duration = t5 + sample_duration + .1; 64 65 //aubio_sampler_set_transpose(sampler, 0.); 66 //aubio_sampler_set_stretch(sampler, .8); 32 67 33 68 do { 34 aubio_source_do(source, vec, &read); 35 if (n_frames / hop_size == 10) { 69 if (time_was_reached(t1, n_frames, hop_size, samplerate)) { 70 PRINT_MSG("`-test one shot play of loaded sample\n"); 71 aubio_sampler_set_loop( sampler, 1); 36 72 aubio_sampler_play ( sampler ); 73 } else if (time_was_reached(t2, n_frames, hop_size, samplerate)) { 74 PRINT_MSG("`-test queueing while playing after eof was reached\n"); 75 //aubio_sampler_queue (sampler, sample_path); 76 //aubio_sampler_play (sampler); 77 aubio_sampler_set_loop( sampler, 0); 78 #if 0 79 } else if (time_was_reached(t3, n_frames, hop_size, samplerate)) { 80 PRINT_MSG("`-test queueing twice cancels the first one\n"); 81 aubio_sampler_queue (sampler, sample_path); 82 aubio_sampler_queue (sampler, sample_path); 83 aubio_sampler_play (sampler); 84 } else if (time_was_reached(t4, n_frames, hop_size, samplerate)) { 85 PRINT_MSG("`-test queueing a corrupt file\n"); 86 aubio_sampler_queue (sampler, "/dev/null"); 87 aubio_sampler_play (sampler); 88 } else if (time_was_reached(t5, n_frames, hop_size, samplerate)) { 89 aubio_sampler_stop ( sampler ); 90 PRINT_MSG("`-test queueing a correct file after a corrupt one\n"); 91 uint_t i; 92 for (i = 0; i < 4; i++) 93 aubio_sampler_queue (sampler, "/dev/null"); 94 aubio_sampler_queue (sampler, "/dev/null1"); 95 aubio_sampler_queue (sampler, "/dev/null2"); 96 aubio_sampler_queue (sampler, sample_path); 97 aubio_sampler_play (sampler); 98 #endif 37 99 } 100 /* 38 101 if (n_frames / hop_size == 40) { 39 aubio_sampler_play ( sampler ); 102 aubio_sampler_queue (sampler, sample_path); 103 aubio_sampler_queue (sampler, sample_path); 104 aubio_sampler_seek ( sampler, 0); 40 105 } 41 106 if (n_frames / hop_size == 70) { 42 aubio_sampler_ play ( sampler);107 aubio_sampler_seek ( sampler, 0); 43 108 } 44 if (n_frames > 10.0 * samplerate) { 45 aubio_sampler_stop ( sampler ); 46 } 47 aubio_sampler_do (sampler, vec, vec); 48 aubio_sink_do(sink, vec, read); 49 n_frames += read; 50 } while ( read == hop_size ); 109 */ 110 aubio_sampler_do (sampler, vec, &read); 111 if (sink) aubio_sink_do(sink, vec, hop_size); 112 n_frames += hop_size; 113 frames_played += read; 114 //} while ( read == hop_size ); 115 // last for 40 seconds 116 } while ( n_frames <= total_duration * samplerate ); 117 PRINT_MSG("reached %.2f sec at %d samples, sampler played %d frames\n", 118 total_duration, n_frames, frames_played); 51 119 120 if (sink) del_aubio_sink(sink); 121 beach_sink: 52 122 del_aubio_sampler(sampler); 53 del_aubio_source(source); 54 del_aubio_sink(sink); 123 beach_sampler: 55 124 del_fvec(vec); 125 beach: 56 126 aubio_cleanup(); 57 58 127 return 0; 59 128 } -
wscript
rb762f8d rb201912 66 66 help_str = 'compile with samplerate (auto)', 67 67 help_disable_str = 'disable samplerate') 68 add_option_enable_disable(ctx, 'rubberband', default = None, 69 help_str = 'compile with rubberband (auto)', 70 help_disable_str = 'disable rubberband') 68 71 add_option_enable_disable(ctx, 'memcpy', default = True, 69 72 help_str = 'use memcpy hacks (default)', … … 118 121 ctx.check(header_name='unistd.h', mandatory = False) 119 122 123 ctx.check(header_name='pthread.h', mandatory = False) 124 needs_pthread = ctx.get_define("HAVE_PTHREAD_H") is not None 125 if needs_pthread: 126 ctx.check_cc(lib="pthread", uselib_store="PTHREAD", mandatory=needs_pthread) 127 120 128 target_platform = sys.platform 121 129 if ctx.options.target_platform: … … 298 306 args = '--cflags --libs samplerate >= 0.0.15', 299 307 mandatory = ctx.options.enable_samplerate) 308 309 # check for librubberband 310 if (ctx.options.enable_rubberband != False): 311 ctx.check_cfg(package = 'rubberband', atleast_version = '1.3', 312 args = '--cflags --libs', 313 mandatory = ctx.options.enable_rubberband) 300 314 301 315 # check for jack
Note: See TracChangeset
for help on using the changeset viewer.