Changes in / [c7d444a:bad88364]
- Files:
-
- 14 added
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
.travis.yml
rc7d444a rbad88364 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 … … 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
rc7d444a rbad88364 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 … … 184 191 def gen_code(self): 185 192 out = "" 186 out += self.gen_struct() 187 out += self.gen_doc() 188 out += self.gen_new() 189 out += self.gen_init() 190 out += self.gen_del() 191 out += self.gen_do() 192 out += self.gen_memberdef() 193 out += self.gen_set() 194 out += self.gen_get() 195 out += self.gen_methodef() 196 out += self.gen_typeobject() 193 try: 194 out += self.gen_struct() 195 out += self.gen_doc() 196 out += self.gen_new() 197 out += self.gen_init() 198 out += self.gen_del() 199 out += self.gen_do() 200 out += self.gen_memberdef() 201 out += self.gen_set() 202 out += self.gen_get() 203 out += self.gen_methodef() 204 out += self.gen_typeobject() 205 except Exception as e: 206 print ("Failed generating code for", self.shortname) 207 raise 197 208 return out 198 209 … … 266 277 if p['type'] == 'char_t*': 267 278 return self.check_valid_char(p) 279 if p['type'] == 'smpl_t': 280 return self.check_valid_smpl(p) 268 281 else: 269 282 print ("ERROR, no idea how to check %s for validity" % p['type']) … … 286 299 self->{name} = {defval}; 287 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.) {{ 288 310 self->{name} = {name}; 289 311 }} -
python/lib/gen_external.py
rc7d444a rbad88364 40 40 #'sampler', 41 41 'audio_unit', 42 'timestretch', # TODO fix parsing of uint_t *read in _do 43 'sampler', # TODO fix parsing of uint_t *read in _do 44 'ringbuffer', 42 45 ] 43 46 -
python/lib/moresetuptools.py
rc7d444a rbad88364 113 113 # loof for additional packages 114 114 print("Info: looking for *optional* additional packages") 115 packages = ['libavcodec', 'libavformat', 'libavutil', 116 'libswresample', 'libavresample', 115 packages = ['libavcodec', 'libavformat', 'libavutil', 'libavresample', 117 116 'sndfile', 117 'rubberband', 118 118 #'fftw3f', 119 119 ] … … 137 137 if 'samplerate' in ext.libraries: 138 138 ext.define_macros += [('HAVE_SAMPLERATE', 1)] 139 if 'rubberband' in ext.libraries: 140 ext.define_macros += [('HAVE_RUBBERBAND', 1)] 139 141 if 'fftw3f' in ext.libraries: 140 142 ext.define_macros += [('HAVE_FFTW3F', 1)] -
src/aubio.h
rc7d444a rbad88364 218 218 #include "pitch/pitchspecacf.h" 219 219 #include "tempo/beattracking.h" 220 #include "effects/pitchshift.h" 221 #include "effects/timestretch.h" 220 222 #include "utils/scale.h" 221 223 #include "utils/hist.h" 224 #include "utils/ringbuffer.h" 222 225 #endif 223 226 -
src/io/source_avcodec.c
rc7d444a rbad88364 58 58 #define AUBIO_AVCODEC_MAX_BUFFER_SIZE FF_MIN_BUFFER_SIZE 59 59 60 #ifdef HAVE_PTHREAD_H 61 // Global mutex to make sure avcodec_open2 is not called simultaneously in a 62 // multithreaded environment. Comment the following define if no lock required. 63 #define HAVE_AUBIO_AVCODEC_MUTEX 64 #include <pthread.h> 65 pthread_mutex_t aubio_avcodec_mutex = PTHREAD_MUTEX_INITIALIZER; 66 #endif /* HAVE_PTHREAD_H */ 67 60 68 struct _aubio_source_avcodec_t { 61 69 uint_t hop_size; … … 84 92 uint_t eof; 85 93 uint_t multi; 94 uint_t has_network_url; 86 95 }; 87 96 … … 98 107 av_url_split(proto, proto_size, authorization, authorization_size, hostname, 99 108 hostname_size, port_ptr, uripath, path_size, s->path); 109 s->has_network_url = 0; 100 110 if (strlen(proto)) { 101 return1;102 } 103 return 0;111 s->has_network_url = 1; 112 } 113 return s->has_network_url; 104 114 } 105 115 … … 128 138 strncpy(s->path, path, strnlen(path, PATH_MAX) + 1); 129 139 140 #ifdef HAVE_AUBIO_AVCODEC_MUTEX 141 pthread_mutex_lock(&aubio_avcodec_mutex); 142 #endif /* HAVE_AUBIO_AVCODEC_MUTEX */ 143 130 144 // register all formats and codecs 131 145 av_register_all(); … … 137 151 // try opening the file and get some info about it 138 152 AVFormatContext *avFormatCtx = s->avFormatCtx; 153 AVDictionary *streamopts = 0; 154 if (s->has_network_url) { 155 if (av_dict_set(&streamopts, "timeout", "1000000", 0)) { // in microseconds 156 AUBIO_WRN("source_avcodec: Failed setting timeout to 1000000 for %s\n", s->path); 157 } else { 158 AUBIO_WRN("source_avcodec: Setting timeout to 1000000 for %s\n", s->path); 159 } 160 } 139 161 avFormatCtx = NULL; 140 if ( (err = avformat_open_input(&avFormatCtx, s->path, NULL, NULL) ) < 0 ) {162 if ( (err = avformat_open_input(&avFormatCtx, s->path, NULL, &streamopts) ) < 0 ) { 141 163 char errorstr[256]; 142 164 av_strerror (err, errorstr, sizeof(errorstr)); 143 165 AUBIO_ERR("source_avcodec: Failed opening %s (%s)\n", s->path, errorstr); 144 goto beach ;166 goto beach_streamopts; 145 167 } 146 168 … … 229 251 } 230 252 253 #ifdef HAVE_AUBIO_AVCODEC_MUTEX 254 pthread_mutex_unlock(&aubio_avcodec_mutex); 255 #endif /* HAVE_AUBIO_AVCODEC_MUTEX */ 256 231 257 /* get input specs */ 232 258 s->input_samplerate = avCodecCtx->sample_rate; … … 270 296 //av_log_set_level(AV_LOG_QUIET); 271 297 298 av_dict_free(&streamopts); 272 299 return s; 273 300 301 beach_streamopts: 302 av_dict_free(&streamopts); 274 303 beach: 275 304 //AUBIO_ERR("can not read %s at samplerate %dHz with a hop_size of %d\n", 276 305 // s->path, s->samplerate, s->hop_size); 306 #ifdef HAVE_AUBIO_AVCODEC_MUTEX 307 pthread_mutex_unlock(&aubio_avcodec_mutex); 308 #endif /* HAVE_AUBIO_AVCODEC_MUTEX */ 277 309 del_aubio_source_avcodec(s); 278 310 return NULL; -
src/synth/sampler.c
rc7d444a rbad88364 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 "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 #ifdef HAVE_THREADS 80 // file reading thread 81 pthread_t read_thread; 82 uint_t threaded_read; // use reading thread? 83 pthread_mutex_t read_mutex; 84 pthread_cond_t read_avail; 85 pthread_cond_t read_request; 86 uint_t source_blocksize; 87 fvec_t *source_output; 88 fvec_t *source_output_tmp; 89 uint_t last_read; 90 fmat_t *source_moutput; 91 uint_t channels; 92 // file opening thread 93 pthread_t open_thread; 94 pthread_mutex_t open_mutex; 95 uint_t waited; // number of frames skipped while opening 96 char_t *next_uri; 97 uint_t open_thread_running; 98 sint_t available; // number of samples currently available 99 uint_t started; // source warmed up 100 uint_t read_thread_finish; // flag to tell reading thread to exit 101 #endif 36 102 }; 37 103 38 aubio_sampler_t *new_aubio_sampler(uint_t samplerate, uint_t blocksize) 104 static sint_t aubio_sampler_pull_from_source(aubio_sampler_t *s); 105 106 static void aubio_sampler_do_eof(aubio_sampler_t *s); 107 108 static void aubio_sampler_read(aubio_sampler_t *s, fvec_t *output, uint_t *read); 109 static void aubio_sampler_read_from_source(aubio_sampler_t *s, fvec_t *output, uint_t *read); 110 static void aubio_sampler_read_from_table(aubio_sampler_t *s, fvec_t *output, uint_t *read); 111 112 #ifdef HAVE_THREADS 113 static void *aubio_sampler_openfn(void *p); 114 static void *aubio_sampler_readfn(void *p); 115 static void aubio_sampler_open_opening_thread(aubio_sampler_t *o); 116 static void aubio_sampler_open_reading_thread(aubio_sampler_t *o); 117 static void aubio_sampler_close_opening_thread(aubio_sampler_t *o); 118 static void aubio_sampler_close_reading_thread(aubio_sampler_t *o); 119 #endif 120 121 aubio_sampler_t *new_aubio_sampler(uint_t blocksize, uint_t samplerate) 39 122 { 40 123 aubio_sampler_t *s = AUBIO_NEW(aubio_sampler_t); … … 45 128 s->samplerate = samplerate; 46 129 s->blocksize = blocksize; 47 s->source_output = new_fvec(blocksize);48 s->source_output_multi = new_fmat(4, blocksize);49 130 s->source = NULL; 50 131 s->playing = 0; 132 s->loop = 0; 133 s->uri = NULL; 134 s->finished = 1; 135 s->eof = 0; 136 s->opened = 0; 137 s->available = 0; 138 139 s->threaded_read = 0; 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 s->threaded_read = 0; 153 #endif 154 155 if (s->source_blocksize < s->blocksize) { 156 s->source_blocksize = s->blocksize; 157 } 158 // FIXME: perfectloop fails if source_blocksize > 2048 with source_avcodec 159 //s->source_blocksize = 8192; 160 161 if (s->perfectloop || s->source_blocksize != s->blocksize) { 162 s->ring = new_aubio_ringbuffer(s->source_blocksize * 2, s->blocksize); 163 } 164 if (s->threaded_read || s->perfectloop || s->ring) 165 s->source_output = new_fvec(s->source_blocksize); 166 //s->channels = 1; 167 //s->source_moutput = new_fmat(s->source_blocksize, s->channels); 168 169 #ifdef HAVE_THREADS 170 aubio_sampler_open_opening_thread(s); 171 172 if (s->threaded_read) { 173 //AUBIO_WRN("sampler: starting reading thread\n"); 174 aubio_sampler_open_reading_thread(s); 175 } 176 #endif 177 178 #if 0 179 s->reading_from = aubio_sampler_reading_from_table; 180 s->perfectloop = 1; 181 s->threaded_read = 0; 182 s->opened = 1; 183 s->finished = 1; 184 s->table_index = 0; 185 #endif 186 187 s->ts = new_aubio_timestretch("default", 1., s->blocksize, s->samplerate); 188 s->source_output_tmp = new_fvec(s->source_blocksize); 189 s->last_read = 0; 190 51 191 return s; 52 192 beach: … … 55 195 } 56 196 197 #ifdef HAVE_THREADS 198 void aubio_sampler_open_opening_thread(aubio_sampler_t *s) { 199 pthread_mutex_init(&s->open_mutex, 0); 200 s->waited = 0; 201 s->open_thread = 0; 202 s->open_thread_running = 0; 203 } 204 205 void aubio_sampler_open_reading_thread(aubio_sampler_t *s) { 206 s->read_thread_finish = 0; 207 pthread_mutex_init(&s->read_mutex, 0); 208 pthread_cond_init (&s->read_avail, 0); 209 pthread_cond_init (&s->read_request, 0); 210 pthread_create(&s->read_thread, 0, aubio_sampler_readfn, s); 211 } 212 213 void aubio_sampler_close_opening_thread(aubio_sampler_t *o) { 214 // clean up opening thread 215 void *threadret; 216 if (!o->open_thread) return; 217 pthread_mutex_destroy(&o->open_mutex); 218 if (o->open_thread_running) { 219 if (pthread_cancel(o->open_thread)) { 220 AUBIO_WRN("sampler: cancelling file opening thread failed\n"); 221 } 222 } 223 if (o->open_thread && pthread_join(o->open_thread, &threadret)) { 224 AUBIO_WRN("sampler: joining file opening thread failed\n"); 225 } 226 pthread_mutex_destroy(&o->open_mutex); 227 o->open_thread = 0; 228 } 229 230 void aubio_sampler_close_reading_thread(aubio_sampler_t *o) { 231 // clean up reading thread 232 void *threadret; 233 if (!o->read_thread) return; 234 o->read_thread_finish = 1; 235 pthread_cond_signal(&o->read_request); 236 if (pthread_cancel(o->read_thread)) { 237 AUBIO_WRN("sampler: cancelling file reading thread failed\n"); 238 } 239 if (pthread_join(o->read_thread, &threadret)) { 240 AUBIO_WRN("sampler: joining file reading thread failed\n"); 241 } 242 pthread_mutex_destroy(&o->read_mutex); 243 pthread_cond_destroy(&o->read_avail); 244 pthread_cond_destroy(&o->read_request); 245 o->read_thread = 0; 246 } 247 #endif 248 57 249 uint_t aubio_sampler_load( aubio_sampler_t * o, const char_t * uri ) 58 250 { 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; 251 uint_t ret = AUBIO_FAIL; 252 aubio_source_t *oldsource = o->source, *newsource = NULL; 253 newsource = new_aubio_source(uri, o->samplerate, o->source_blocksize); 254 if (newsource) { 255 uint_t duration = aubio_source_get_duration(newsource); 256 if (duration < o->blocksize) { 257 AUBIO_WRN("sampler: %s is %d frames long, but blocksize is %d\n", 258 uri, duration, o->blocksize); 259 } 260 o->source = newsource; 261 if (oldsource) del_aubio_source(oldsource); 262 if (o->samplerate == 0) { 263 o->samplerate = aubio_source_get_samplerate(o->source); 264 } 265 if (o->uri) AUBIO_FREE(o->uri); 266 o->uri = AUBIO_ARRAY(char_t, strnlen(uri, PATH_MAX) + 1); 267 strncpy(o->uri, uri, strnlen(uri, PATH_MAX) + 1); 268 o->finished = 0; 269 o->eof = 0; 270 o->eof_remaining = 0; 271 o->opened = 1; 272 ret = AUBIO_OK; 273 AUBIO_MSG("sampler: loaded %s\n", uri); 274 if (o->waited) { 275 AUBIO_WRN("sampler: %.2fms (%d samples) taken to load %s\n", 1000. * 276 o->waited / (smpl_t)o->samplerate, o->waited, o->uri); 277 } 278 } else { 279 o->source = NULL; 280 if (oldsource) del_aubio_source(oldsource); 281 o->playing = 0; 282 o->uri = NULL; 283 o->finished = 1; 284 o->eof = 0; 285 o->eof_remaining = 0; 286 o->opened = 0; 287 AUBIO_WRN("sampler: failed loading %s\n", uri); 288 } 289 if (o->ring) { 290 //AUBIO_WRN("sampler: resetting ringbuffer\n"); 291 aubio_ringbuffer_reset(o->ring); 292 } 293 return ret; 294 } 295 296 #ifdef HAVE_THREADS 297 static void *aubio_sampler_openfn(void *z) { 298 aubio_sampler_t *p = z; 299 uint_t err; 300 int oldtype; 301 void *ret; 302 pthread_setcancelstate(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); 303 pthread_mutex_lock(&p->open_mutex); 304 p->open_thread_running = 1; 305 err = aubio_sampler_load(p, p->next_uri); 306 p->open_thread_running = 0; 307 pthread_mutex_unlock(&p->open_mutex); 308 ret = &err; 309 pthread_exit(ret); 310 } 311 #endif 312 313 uint_t 314 aubio_sampler_queue(aubio_sampler_t *o, const char_t *uri) 315 { 316 #ifdef HAVE_THREADS 317 uint_t ret = AUBIO_OK; 318 319 if (o->reading_from == aubio_sampler_reading_from_table) { 320 o->reading_from = aubio_sampler_reading_from_source; 321 o->opened = 0; 322 o->finished = 1; 323 } 324 /* open uri in open_thread */ 325 if (o->open_thread_running) { 326 // cancel previous open_thread 327 if (pthread_cancel(o->open_thread)) { 328 AUBIO_WRN("sampler: failed queuing %s (cancelling existing open thread failed)\n", uri); 329 return AUBIO_FAIL; 330 } else { 331 AUBIO_WRN("sampler: cancelled queuing %s (queuing %s now)\n", 332 o->next_uri, uri); 333 } 334 o->open_thread_running = 0; 335 } 336 void *threadret; 337 if (o->open_thread && pthread_join(o->open_thread, &threadret)) { 338 AUBIO_WRN("sampler: joining thread failed\n"); 339 } 340 if (pthread_mutex_trylock(&o->open_mutex)) { 341 AUBIO_WRN("sampler: failed queuing %s (locking failed)\n", uri); 342 ret = AUBIO_FAIL; 343 goto lock_failed; 344 } 345 o->opened = 0; // while opening 346 o->started = 0; 347 o->available = 0; 348 if (o->next_uri) AUBIO_FREE(o->next_uri); 349 o->next_uri = AUBIO_ARRAY(char_t, strnlen(uri, PATH_MAX) + 1); 350 strncpy(o->next_uri, uri, strnlen(uri, PATH_MAX) + 1); 351 o->waited = 0; 352 if (pthread_create(&o->open_thread, 0, aubio_sampler_openfn, o) != 0) { 353 AUBIO_ERR("sampler: failed creating opening thread\n"); 354 ret = AUBIO_FAIL; 355 goto thread_create_failed; 356 } 357 358 thread_create_failed: 359 pthread_mutex_unlock(&o->open_mutex); 360 lock_failed: 361 if (ret == AUBIO_OK) { 362 //AUBIO_WRN("sampler: queued %s\n", uri); 363 } else { 364 AUBIO_ERR("sampler: queueing %s failed\n", uri); 365 } 366 return ret; 367 #else 368 AUBIO_WRN("sampler: opening %s, not queueing (not compiled with threading)\n", uri); 369 return aubio_sampler_load(o, uri); 370 #endif 371 } 372 373 #ifdef HAVE_THREADS 374 375 uint_t aubio_sampler_reading_from_source_ring_fetch(aubio_sampler_t*s); 376 377 void *aubio_sampler_readfn(void *z) { 378 aubio_sampler_t *p = z; 379 while(1) { 380 pthread_mutex_lock(&p->read_mutex); 381 if (p->open_thread_running) { 382 //AUBIO_WRN("sampler: readfn(): file is being opened\n"); 383 pthread_cond_signal(&p->read_avail); 384 //pthread_cond_wait(&p->read_request, &p->read_mutex); 385 } else if (p->opened && !p->started && !p->finished) { 386 //AUBIO_WRN("sampler: readfn(): file started\n"); 387 if (p->ring) { 388 p->available = aubio_sampler_reading_from_source_ring_fetch(p); 389 } else { 390 p->available = aubio_sampler_pull_from_source(p); 391 if (p->available < (sint_t)p->source_blocksize) 392 aubio_sampler_do_eof(p); 393 } 394 pthread_cond_signal(&p->read_avail); 395 if (!p->finished) { 396 pthread_cond_wait(&p->read_request, &p->read_mutex); 397 } 398 } else { 399 //AUBIO_WRN("sampler: readfn(): idle?\n"); 400 pthread_cond_signal(&p->read_avail); 401 pthread_cond_wait(&p->read_request, &p->read_mutex); 402 if (p->read_thread_finish) { 403 goto done; 404 } 405 } 406 pthread_mutex_unlock(&p->read_mutex); 407 } 408 done: 409 //AUBIO_WRN("sampler: exiting reading thread\n"); 410 pthread_mutex_unlock(&p->read_mutex); 411 pthread_exit(NULL); 412 } 413 #endif 414 415 void 416 aubio_sampler_read(aubio_sampler_t *s, fvec_t *output, uint_t *read) { 417 if (s->reading_from == aubio_sampler_reading_from_source) { 418 aubio_sampler_read_from_source(s, output, read); 419 } else if (s->reading_from == aubio_sampler_reading_from_table) { 420 aubio_sampler_read_from_table(s, output, read); 421 } 422 } 423 424 static void 425 aubio_sampler_reading_from_source_naive(aubio_sampler_t *s, fvec_t * output, 426 uint_t *read) 427 { 428 // directly read from disk 429 //aubio_source_do(s->source, output, read); 430 s->source_output = output; 431 *read = aubio_sampler_pull_from_source(s); 432 if (*read < s->source_blocksize) { 433 //AUBIO_WRN("sampler: calling go_eof in _read_from_source()\n"); 434 aubio_sampler_do_eof(s); 435 } 436 } 437 438 uint_t 439 aubio_sampler_reading_from_source_ring_fetch(aubio_sampler_t*s) { 440 // read source_blocksize (> blocksize) at once 441 int ring_avail = aubio_ringbuffer_get_available(s->ring); 442 //if (ring_avail < s->blocksize) { 443 uint_t available = 0; 444 if (ring_avail < (sint_t)s->blocksize) { 445 available = aubio_sampler_pull_from_source(s); 446 if (available > 0) { 447 aubio_ringbuffer_push(s->ring, s->source_output, available); 448 } 449 if (available < s->blocksize) { 450 //AUBIO_WRN("sampler: short read %d\n", available); 451 if (ring_avail + available <= s->blocksize) { 452 s->eof_remaining = available + ring_avail; 453 if (s->eof_remaining == 0) s->eof_remaining = s->blocksize; 454 ring_avail = aubio_ringbuffer_get_available(s->ring); 455 //AUBIO_ERR("sampler: eof in: %d, last fetch: %d, in ring: %d\n", 456 // s->eof_remaining, available, ring_avail); 457 if (s->loop) { 458 aubio_sampler_seek(s,0); 459 // read some frames from beginning of source for perfect looping 460 if (s->perfectloop) { 461 available = aubio_sampler_pull_from_source(s); 462 if (available <= 0) { 463 AUBIO_ERR("sampler: perfectloop but s->available = 0 !\n"); 464 } else { 465 aubio_ringbuffer_push(s->ring, s->source_output, available); 466 } 467 } 468 } 469 } 470 } 471 } 472 return available; 473 } 474 475 static void 476 aubio_sampler_reading_from_source_ring_pull(aubio_sampler_t *s, fvec_t *output, 477 uint_t *read) 478 { 479 // write into output 480 int ring_avail = aubio_ringbuffer_get_available(s->ring); 481 if (ring_avail >= (sint_t)s->blocksize) { 482 //AUBIO_MSG("sampler: pulling %d / %d from ringbuffer\n", s->blocksize, ring_avail); 483 aubio_ringbuffer_pull(s->ring, output, s->blocksize); 484 *read = s->blocksize; 485 if (s->eof_remaining > 0) { 486 if (s->eof_remaining <= s->blocksize) { 487 //AUBIO_WRN("sampler: signaling eof\n"); 488 s->eof = 1; // signal eof 489 s->eof_remaining = 0; 490 } else if (s->eof_remaining <= s->source_blocksize) { 491 s->eof_remaining -= s->blocksize; 492 } 493 } 494 } else { 495 //AUBIO_MSG("sampler: last frame, pulling remaining %d left\n", ring_avail); 496 *read = 0; 497 if (ring_avail > 0) { 498 // pull remaining frames in ring buffer 499 aubio_ringbuffer_pull(s->ring, output, ring_avail); 500 *read += ring_avail; 501 } 502 // signal eof 503 aubio_sampler_do_eof(s); 504 // finished playing, reset ringbuffer for next read 505 if (!s->playing) 506 aubio_ringbuffer_reset(s->ring); 507 } 508 } 509 510 static void 511 aubio_sampler_reading_from_source_ring(aubio_sampler_t *s, fvec_t *output, 512 uint_t *read) 513 { 514 #if 0 515 aubio_sampler_reading_from_source_ring_fetch(s); 516 aubio_sampler_reading_from_source_ring_pull(s, output, read); 517 #else // raw version 518 uint_t source_read; 519 while (aubio_timestretch_get_available(s->ts) < (sint_t)s->blocksize 520 && s->eof_remaining == 0) { 521 aubio_source_do(s->source, s->source_output, &source_read); 522 aubio_timestretch_push(s->ts, s->source_output, source_read); 523 if (source_read < s->source_output->length) s->eof_remaining = source_read; 524 //AUBIO_WRN("sampler: pushed %d, now %d available\n", 525 // source_read, aubio_timestretch_get_available(s->ts)); 526 } 527 aubio_timestretch_do(s->ts, output, read); 528 if (s->eof_remaining > s->blocksize) { 529 s->eof_remaining -= s->blocksize; 530 } 531 if (*read < output->length) { 532 //AUBIO_WRN("sampler: short read %d, eof at %d\n", *read, s->eof_remaining); 533 s->eof_remaining = 0; 534 aubio_timestretch_reset(s->ts); 535 aubio_sampler_do_eof(s); 536 if (s->loop && s->perfectloop) { 537 fvec_t tmpout; tmpout.data = output->data + *read; 538 tmpout.length = output->length - *read; 539 uint_t partialread; 540 while (aubio_timestretch_get_available(s->ts) < (sint_t)tmpout.length 541 && s->eof_remaining == 0) { 542 aubio_source_do(s->source, s->source_output, &source_read); 543 aubio_timestretch_push(s->ts, s->source_output, source_read); 544 if (source_read < s->source_output->length) s->eof_remaining = source_read; 545 } 546 aubio_timestretch_do(s->ts, &tmpout, &partialread); 547 //AUBIO_WRN("sampler: partial read %d + %d\n", *read, partialread); 548 *read += partialread; 549 } 550 } 551 #endif 552 } 553 554 #ifdef HAVE_THREADS 555 static void 556 aubio_sampler_read_from_source_threaded(aubio_sampler_t *s, fvec_t *output, 557 uint_t *read) { 558 // request at least output->length 559 // make sure we have enough samples read from source 560 int available; 561 pthread_mutex_lock(&s->read_mutex); 562 if (!s->opened || s->open_thread_running) { 563 //AUBIO_ERR("sampler: _read_from_source: not opened, signaling read_request\n"); 564 pthread_cond_signal(&s->read_request); 565 available = 0; 566 } else if (!s->finished) { 567 pthread_cond_signal(&s->read_request); 568 pthread_cond_wait(&s->read_avail, &s->read_mutex); 569 //AUBIO_ERR("sampler: _read_from_source: %d\n", s->available); 570 available = s->available; 571 } else { 572 //AUBIO_WRN("sampler: _read_from_source: eof\n"); 573 pthread_cond_signal(&s->read_request); 574 available = 0; 575 } 576 pthread_mutex_unlock(&s->read_mutex); 577 //AUBIO_WRN("sampler: got %d available in _read_from_source\n", available); 578 // read -> number of samples read 579 if (!s->perfectloop && s->source_blocksize == s->blocksize) { 580 if (available >= (sint_t)s->blocksize) { 581 fvec_copy(s->source_output, output); 582 *read = s->blocksize; 583 } else if (available > 0) { 584 fvec_copy(s->source_output, output); 585 *read = available; 586 } else { 587 fvec_zeros(output); 588 *read = 0; 589 } 590 } else { 591 aubio_sampler_reading_from_source_ring_pull(s, output, read); 592 } 593 } 594 #endif 595 596 void 597 aubio_sampler_read_from_source(aubio_sampler_t *s, fvec_t *output, uint_t *read) { 598 #ifdef HAVE_THREADS 599 if (s->threaded_read) { // if threaded 600 aubio_sampler_read_from_source_threaded(s, output, read); 601 } else 602 #endif 603 { 604 if (s->finished) { 605 *read = 0; 606 } 607 else if (s->source_blocksize == s->blocksize && !s->perfectloop) { 608 aubio_sampler_reading_from_source_naive(s, output, read); 609 } else { 610 aubio_sampler_reading_from_source_ring(s, output, read); 611 } 612 #if 1 613 if (s->loop && s->perfectloop && *read != s->blocksize) { // && s->started && !s->finished) { 614 AUBIO_ERR("sampler: perfectloop but read only %d\n", *read); 615 } 616 #endif 617 } 618 } 619 620 void 621 aubio_sampler_read_from_table(aubio_sampler_t *s, fvec_t *output, uint_t *read) { 622 *read = 0; 623 if (s->table == NULL) { 624 AUBIO_WRN("sampler: _pull_from_table but table not set %d, %d\n", 625 output->length, *read); 626 } else if (s->playing) { 627 #if 0 628 uint_t available = s->table->length - s->table_index; 629 fvec_t tmp; 630 tmp.data = s->table->data + s->table_index; 631 if (available < s->blocksize) { 632 //AUBIO_WRN("sampler: _pull_from_table: table length %d, index: %d, read %d\n", 633 // s->table->length, s->table_index, *read); 634 tmp.length = available; 635 fvec_t tmpout; tmpout.data = output->data; tmpout.length = available; 636 fvec_copy(&tmp, &tmpout); 637 if (s->loop && s->perfectloop) { 638 uint_t remaining = s->blocksize - available; 639 tmpout.data = output->data + available; tmpout.length = remaining; 640 tmp.data = s->table->data; tmp.length = remaining; 641 fvec_copy(&tmp, &tmpout); 642 s->table_index = remaining; 643 *read = s->blocksize; 644 } else { 645 s->table_index = 0; 646 *read = available; 647 } 648 aubio_sampler_do_eof(s); 649 } else { 650 tmp.length = s->blocksize; 651 fvec_copy(&tmp, output); 652 s->table_index += output->length; 653 *read = s->blocksize; 654 } 655 #else 656 fvec_t tmp, tmpout; 657 uint_t source_read = 0; 658 while (aubio_timestretch_get_available(s->ts) < (sint_t)s->blocksize 659 && s->eof_remaining == 0) { 660 uint_t available = s->table->length - s->table_index; 661 if (available < s->source_blocksize) { 662 source_read = available; 663 } else { 664 source_read = s->source_blocksize; 665 } 666 tmp.length = source_read; tmp.data = s->table->data + s->table_index; 667 tmpout.data = s->source_output->data; tmpout.length = source_read; 668 fvec_copy(&tmp, &tmpout); 669 aubio_timestretch_push(s->ts, &tmpout, source_read); 670 if (source_read < s->source_blocksize) { 671 s->eof_remaining = source_read; 672 s->table_index = s->source_blocksize - *read; 673 } else { 674 s->table_index += source_read; 675 } 676 if (s->table_index == s->table->length) s->table_index = 0; 677 //AUBIO_WRN("sampler: pushed %d, now %d available, table_index %d, eof %d\n", 678 // source_read, aubio_timestretch_get_available(s->ts), 679 // s->table_index, s->eof_remaining); 680 } 681 aubio_timestretch_do(s->ts, output, read); 682 if (*read == 0) { 683 //AUBIO_WRN("sampler: pushed %d, now %d available, table_index %d\n", 684 // *read, aubio_timestretch_get_available(s->ts), s->table_index); 685 } 686 if (s->eof_remaining > s->blocksize) { 687 s->eof_remaining -= s->blocksize; 688 } 689 if (*read < output->length) { 690 s->eof_remaining = 0; 691 aubio_sampler_do_eof(s); 692 } 693 #if 0 694 if (*read < output->length) { 695 //uint_t available = aubio_timestretch_get_available(s->ts); 696 s->eof_remaining = 0; 697 aubio_timestretch_reset(s->ts); 698 aubio_sampler_do_eof(s); 699 } 700 #endif 701 #if 0 702 if (*read < output->length) { 703 //uint_t available = aubio_timestretch_get_available(s->ts); 704 s->eof_remaining = 0; 705 aubio_timestretch_reset(s->ts); 706 aubio_sampler_do_eof(s); 707 if (s->loop && s->perfectloop) { 708 tmpout.data = output->data + *read; 709 tmpout.length = output->length - *read; 710 while (aubio_timestretch_get_available(s->ts) < (sint_t)tmpout.length 711 && s->eof_remaining == 0) { 712 uint_t available = s->table->length - s->table_index; 713 if (available < s->source_blocksize) { 714 source_read = available; 715 } else { 716 source_read = s->source_blocksize; 717 } 718 //AUBIO_WRN("sampler: short read %d, remaining %d\n", *read, remaining); 719 tmp.length = source_read; tmp.data = s->table->data + s->table_index; 720 fvec_t tmpout2; tmpout2.data = s->source_output->data; tmpout2.length = source_read; 721 fvec_copy(&tmp, &tmpout2); 722 aubio_timestretch_push(s->ts, &tmpout2, source_read); 723 if (source_read < s->source_blocksize) { 724 s->eof_remaining = source_read; 725 s->table_index = 0; 726 } else { 727 s->table_index += source_read; 728 } 729 if (s->table_index == s->table->length) s->table_index = 0; 730 //AUBIO_WRN("sampler: second push, pushed %d, now %d available\n", 731 // source_read, aubio_timestretch_get_available(s->ts)); 732 } 733 uint_t partialread; 734 aubio_timestretch_do(s->ts, &tmpout, &partialread); 735 AUBIO_WRN("sampler: partial read %d + %d\n", *read, partialread); 736 *read += partialread; 737 //s->eof = 1; 738 } 739 } 740 #endif 741 742 #endif 743 } 744 } 745 746 uint_t 747 aubio_sampler_set_table(aubio_sampler_t *s, fvec_t *samples) { 748 if (!samples || !s) return AUBIO_FAIL; 749 if (s->reading_from == aubio_sampler_reading_from_source) { 750 //aubio_sampler_close_reading_thread(s); 751 } 752 s->table = samples; 753 //AUBIO_INF("sampler: setting table (%d long)\n", s->table->length); 754 s->table_index = 0; 755 s->reading_from = aubio_sampler_reading_from_table; 756 //s->threaded_read = 0; 757 s->opened = 1; 758 s->finished = 1; 759 return AUBIO_OK; 760 } 761 762 sint_t 763 aubio_sampler_pull_from_source(aubio_sampler_t *s) 764 { 765 // pull source_blocksize samples from source, return available frames 766 uint_t source_read = s->source_blocksize; 767 if (s->source == NULL) { 768 AUBIO_ERR("sampler: trying to fetch on NULL source\n"); 769 return -1; 770 } 771 #if 1 772 aubio_source_do(s->source, s->source_output, &source_read); 773 return source_read; 774 #else 775 uint_t source_read_tmp; 776 while (aubio_timestretch_get_available(s->ts) < (sint_t)s->blocksize 777 && s->last_read == 0) { 778 aubio_source_do(s->source, s->source_output_tmp, &source_read_tmp); 779 aubio_timestretch_push(s->ts, s->source_output_tmp, source_read_tmp); 780 if (source_read_tmp < s->source_output_tmp->length) s->last_read = source_read; 781 } 782 aubio_timestretch_do(s->ts, s->source_output, &source_read); 783 if (s->last_read > s->blocksize) { 784 s->last_read -= s->blocksize; 785 } 786 if (source_read < s->source_blocksize) { 787 s->last_read = 0; 788 //AUBIO_ERR("sampler: calling timestretch reset %d %d\n", source_read, s->source_blocksize); 789 aubio_timestretch_reset(s->ts); 790 } 791 return source_read; 792 #endif 793 } 794 795 796 uint_t 797 aubio_sampler_get_samplerate (aubio_sampler_t *o) 798 { 799 return o->samplerate; 800 } 801 802 uint_t 803 aubio_sampler_get_opened (aubio_sampler_t *o) 804 { 805 return o->opened; //== 1 ? AUBIO_OK : AUBIO_FAIL; 806 } 807 808 uint_t 809 aubio_sampler_get_finished(aubio_sampler_t *o) 810 { 811 return o->finished; 812 } 813 814 uint_t 815 aubio_sampler_get_eof (aubio_sampler_t *o) 816 { 817 return o->eof; 818 } 819 820 uint_t 821 aubio_sampler_get_waited_opening (aubio_sampler_t *o, uint_t waited) { 822 #ifdef HAVE_THREADS 74 823 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 } 824 if (!o->opened) { 825 o->waited += waited; 826 } else if (o->waited) { 827 //AUBIO_WRN("sampler: waited %d frames (%.2fms) while opening %s\n", 828 // o->waited, 1000.*o->waited/(smpl_t)o->samplerate, o->uri); 829 uint_t waited = o->waited; 830 o->waited = 0; 831 return waited; 832 } 833 } 834 #endif 835 return 0; 836 } 837 838 uint_t 839 aubio_sampler_seek(aubio_sampler_t * o, uint_t pos) 840 { 841 //AUBIO_WRN("sampler: seeking to 0\n"); 842 uint_t ret = AUBIO_FAIL; 843 o->finished = 0; 844 if (!o->opened) return AUBIO_OK; 845 if (o->source) { 846 ret = aubio_source_seek(o->source, pos); 847 } else if (o->table && (sint_t)pos >= 0 && pos < o->table->length) { 848 o->table_index = pos < o->table->length ? pos : o->table->length - 1; 849 ret = AUBIO_OK; 850 } 851 o->last_read = 0; 852 return ret; 853 } 854 855 void 856 aubio_sampler_do_eof (aubio_sampler_t * o) 857 { 858 //AUBIO_MSG("sampler: calling _do_eof()\n"); 859 o->finished = 1; 860 o->eof = 1; 861 if (!o->loop) { 862 o->playing = 0; 863 } else { 864 if (o->reading_from == aubio_sampler_reading_from_source) 865 aubio_sampler_seek(o, 0); 866 //o->finished = 0; 867 } 868 } 869 870 void aubio_sampler_do ( aubio_sampler_t * o, fvec_t * output, uint_t *read) 871 { 872 o->eof = 0; 873 if (o->opened == 1 && o->playing) { 874 aubio_sampler_read(o, output, read); 875 } else { 876 fvec_zeros(output); 877 *read = 0; 878 } 879 } 880 881 void aubio_sampler_do_multi ( aubio_sampler_t * o, fmat_t * output, uint_t *read) 882 { 883 o->eof = 0; 884 if (o->opened == 1 && o->playing) { 885 //aubio_sampler_read_multi(o, output, read); 886 } else { 887 fmat_zeros(output); 888 *read = 0; 106 889 } 107 890 } … … 118 901 } 119 902 903 uint_t aubio_sampler_get_loop ( aubio_sampler_t * o ) 904 { 905 return o->loop; 906 } 907 908 uint_t aubio_sampler_set_loop ( aubio_sampler_t * o, uint_t loop ) 909 { 910 o->loop = (loop == 1) ? 1 : 0; 911 return 0; 912 } 913 120 914 uint_t aubio_sampler_play ( aubio_sampler_t * o ) 121 915 { 122 aubio_source_seek (o->source, 0);123 916 return aubio_sampler_set_playing (o, 1); 124 917 } … … 129 922 } 130 923 924 uint_t aubio_sampler_loop ( aubio_sampler_t * o ) 925 { 926 aubio_sampler_set_loop(o, 1); 927 aubio_sampler_seek(o, 0); 928 return aubio_sampler_set_playing (o, 1); 929 } 930 931 uint_t aubio_sampler_trigger ( aubio_sampler_t * o ) 932 { 933 if (o->ring) aubio_ringbuffer_reset(o->ring); 934 aubio_sampler_set_loop(o, 0); 935 aubio_sampler_seek(o, 0); 936 return aubio_sampler_set_playing (o, 1); 937 } 938 939 uint_t aubio_sampler_set_perfectloop (aubio_sampler_t *s, uint_t perfectloop) { 940 if (!s) return AUBIO_FAIL; 941 s->perfectloop = perfectloop; 942 return AUBIO_OK; 943 } 944 945 uint_t aubio_sampler_get_perfectloop (aubio_sampler_t *s) { 946 if (!s) return AUBIO_FAIL; 947 return s->perfectloop; 948 } 949 950 951 uint_t aubio_sampler_set_stretch(aubio_sampler_t *s, smpl_t stretch) 952 { 953 if (!s->ts) return AUBIO_FAIL; 954 return aubio_timestretch_set_stretch(s->ts, stretch); 955 } 956 957 smpl_t aubio_sampler_get_stretch(aubio_sampler_t *s) 958 { 959 if (!s->ts) return 1.; 960 return aubio_timestretch_get_stretch(s->ts); 961 } 962 963 uint_t aubio_sampler_set_transpose(aubio_sampler_t *s, smpl_t transpose) 964 { 965 if (!s->ts) return AUBIO_FAIL; 966 return aubio_timestretch_set_transpose(s->ts, transpose); 967 } 968 969 smpl_t aubio_sampler_get_transpose(aubio_sampler_t *s) 970 { 971 if (!s->ts) return 0.; 972 return aubio_timestretch_get_transpose(s->ts); 973 } 974 975 131 976 void del_aubio_sampler( aubio_sampler_t * o ) 132 977 { 978 #ifdef HAVE_THREADS 979 // close opening thread 980 aubio_sampler_close_opening_thread(o); 981 // close reading thread 982 aubio_sampler_close_reading_thread(o); 983 #endif 984 //if (o->source_output) { 985 if (o->source_output && (o->threaded_read || o->perfectloop)) { 986 del_fvec(o->source_output); 987 } 988 if (o->source_moutput) { 989 del_fmat(o->source_moutput); 990 } 991 if (o->ring) { 992 del_aubio_ringbuffer(o->ring); 993 } 994 if (o->ts) { 995 del_aubio_timestretch(o->ts); 996 } 133 997 if (o->source) { 134 998 del_aubio_source(o->source); 135 999 } 136 if (o->uri) AUBIO_FREE(o->uri);137 del_fvec(o->source_output);138 del_fmat(o->source_output_multi);139 1000 AUBIO_FREE(o); 140 1001 } -
src/synth/sampler.h
rc7d444a rbad88364 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 - add _set_stretch 36 - add _set_pitch 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 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 111 157 /** play sample from start 112 158 … … 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 the eof is being 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
rc7d444a rbad88364 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
rc7d444a rbad88364 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
rc7d444a rbad88364 75 75 help_str = 'compile with samplerate (auto)', 76 76 help_disable_str = 'disable samplerate') 77 add_option_enable_disable(ctx, 'rubberband', default = None, 78 help_str = 'compile with rubberband (auto)', 79 help_disable_str = 'disable rubberband') 77 80 add_option_enable_disable(ctx, 'memcpy', default = True, 78 81 help_str = 'use memcpy hacks (default)', … … 127 130 ctx.check(header_name='unistd.h', mandatory = False) 128 131 132 ctx.check(header_name='pthread.h', mandatory = False) 133 needs_pthread = ctx.get_define("HAVE_PTHREAD_H") is not None 134 if needs_pthread: 135 ctx.check_cc(lib="pthread", uselib_store="PTHREAD", mandatory=needs_pthread) 136 129 137 target_platform = sys.platform 130 138 if ctx.options.target_platform: … … 307 315 args = '--cflags --libs', 308 316 mandatory = ctx.options.enable_samplerate) 317 318 # check for librubberband 319 if (ctx.options.enable_rubberband != False): 320 ctx.check_cfg(package = 'rubberband', atleast_version = '1.3', 321 args = '--cflags --libs', 322 mandatory = ctx.options.enable_rubberband) 309 323 310 324 # check for jack
Note: See TracChangeset
for help on using the changeset viewer.