- Timestamp:
- Oct 4, 2016, 11:16:14 PM (8 years ago)
- Branches:
- sampler
- Children:
- 0a756ea
- Parents:
- 923670d
- Location:
- src/synth
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/synth/sampler.c
r923670d r88042ef 27 27 #include "synth/sampler.h" 28 28 29 #define HAVE_THREADS 1 30 #if 0 31 #undef HAVE_THREADS 32 #endif 33 34 #ifdef HAVE_THREADS 35 #include <pthread.h> 36 #endif 37 29 38 struct _aubio_sampler_t { 30 39 uint_t samplerate; 31 40 uint_t blocksize; 32 41 aubio_source_t *source; 33 fvec_t *source_output; 34 fmat_t *source_output_multi; 35 char_t *uri; 42 const char_t *uri; 36 43 uint_t playing; 44 uint_t opened; 45 uint_t loop; 46 uint_t finished; 47 uint_t eof; 48 #ifdef HAVE_THREADS 49 pthread_t open_thread; // file opening thread 50 pthread_mutex_t open_mutex; 51 uint_t waited; // number of frames skipped while opening 52 const char_t *next_uri; 53 uint_t open_thread_running; 54 sint_t available; // number of samples currently available 55 uint_t started; // source warmed up 56 uint_t finish; // flag to tell reading thread to exit 57 #endif 37 58 }; 38 59 39 aubio_sampler_t *new_aubio_sampler(uint_t samplerate, uint_t blocksize)60 aubio_sampler_t *new_aubio_sampler(uint_t blocksize, uint_t samplerate) 40 61 { 41 62 aubio_sampler_t *s = AUBIO_NEW(aubio_sampler_t); … … 46 67 s->samplerate = samplerate; 47 68 s->blocksize = blocksize; 48 s->source_output = new_fvec(blocksize);49 s->source_output_multi = new_fmat(4, blocksize);50 69 s->source = NULL; 51 70 s->playing = 0; 71 s->loop = 0; 72 s->uri = NULL; 73 s->finished = 1; 74 s->eof = 0; 75 s->opened = 0; 76 77 #ifdef HAVE_THREADS 78 pthread_mutex_init(&s->open_mutex, 0); 79 s->waited = 0; 80 s->open_thread = 0; 81 s->open_thread_running = 0; 82 #endif 52 83 return s; 53 84 beach: … … 58 89 uint_t aubio_sampler_load( aubio_sampler_t * o, const char_t * uri ) 59 90 { 60 if (o->source) del_aubio_source(o->source); 61 62 if (o->uri) AUBIO_FREE(o->uri); 63 o->uri = AUBIO_ARRAY(char_t, strnlen(uri, PATH_MAX)); 64 strncpy(o->uri, uri, strnlen(uri, PATH_MAX)); 65 66 o->source = new_aubio_source(uri, o->samplerate, o->blocksize); 67 if (o->source) return 0; 68 AUBIO_ERR("sampler: failed loading %s", uri); 69 return 1; 70 } 71 72 void aubio_sampler_do ( aubio_sampler_t * o, const fvec_t * input, fvec_t * output) 73 { 74 uint_t read = 0, i; 91 uint_t ret = AUBIO_FAIL; 92 aubio_source_t *oldsource = o->source, *newsource = NULL; 93 newsource = new_aubio_source(uri, o->samplerate, o->blocksize); 94 if (newsource) { 95 o->source = newsource; 96 if (oldsource) del_aubio_source(oldsource); 97 if (o->samplerate == 0) { 98 o->samplerate = aubio_source_get_samplerate(o->source); 99 } 100 o->uri = uri; 101 o->finished = 0; 102 o->eof = 0; 103 o->opened = 1; 104 ret = AUBIO_OK; 105 //AUBIO_WRN("sampler: loaded %s\n", o->uri); 106 } else { 107 o->source = NULL; 108 if (oldsource) del_aubio_source(oldsource); 109 o->playing = 0; 110 o->uri = NULL; 111 o->finished = 1; 112 o->eof = 0; 113 o->opened = 0; 114 AUBIO_WRN("sampler: failed loading %s\n", uri); 115 } 116 return ret; 117 } 118 119 #ifdef HAVE_THREADS 120 static void *aubio_sampler_openfn(void *z) { 121 aubio_sampler_t *p = z; 122 uint_t err; 123 int oldtype; 124 void *ret; 125 pthread_setcancelstate(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); 126 pthread_mutex_lock(&p->open_mutex); 127 p->open_thread_running = 1; 128 err = aubio_sampler_load(p, p->next_uri); 129 p->open_thread_running = 0; 130 pthread_mutex_unlock(&p->open_mutex); 131 ret = &err; 132 pthread_exit(ret); 133 } 134 #endif 135 136 uint_t 137 aubio_sampler_queue(aubio_sampler_t *o, const char_t *uri) 138 { 139 #ifdef HAVE_THREADS 140 uint_t ret = AUBIO_OK; 141 /* open uri in open_thread */ 142 if (o->open_thread_running) { 143 // cancel previous open_thread 144 if (pthread_cancel(o->open_thread)) { 145 AUBIO_WRN("sampler: cancelling open thread failed\n"); 146 return AUBIO_FAIL; 147 } else { 148 AUBIO_WRN("sampler: previous open of %s cancelled while opening %s\n", 149 o->next_uri, uri); 150 } 151 o->open_thread_running = 0; 152 } 153 void *threadret; 154 if (o->open_thread && pthread_join(o->open_thread, &threadret)) { 155 AUBIO_WRN("sampler: joining thread failed\n"); 156 } 157 if (pthread_mutex_trylock(&o->open_mutex)) { 158 AUBIO_WRN("sampler: failed locking in queue\n"); 159 ret = AUBIO_FAIL; 160 goto lock_failed; 161 } 162 o->opened = 0; // while opening 163 o->started = 0; 164 o->available = 0; 165 o->next_uri = uri; 166 if (pthread_create(&o->open_thread, 0, aubio_sampler_openfn, o) != 0) { 167 AUBIO_ERR("sampler: failed creating opening thread\n"); 168 ret = AUBIO_FAIL; 169 goto thread_create_failed; 170 } 171 172 thread_create_failed: 173 pthread_mutex_unlock(&o->open_mutex); 174 lock_failed: 175 if (ret == AUBIO_OK) { 176 //AUBIO_WRN("sampler: queued %s\n", uri); 177 } else { 178 AUBIO_ERR("sampler: queueing %s failed\n", uri); 179 } 180 return ret; 181 #else 182 AUBIO_WRN("sampler: opening %s, not queueing (not compiled with threading)\n", uri); 183 return aubio_sampler_load(o, uri); 184 #endif 185 } 186 187 void 188 aubio_sampler_fetch_from_source(aubio_sampler_t *o, fvec_t *output, uint_t *read) { 189 if (o->opened == 1 && o->source && !o->finished) 190 aubio_source_do(o->source, output, read); 191 } 192 193 void 194 aubio_sampler_fetch_from_source_multi(aubio_sampler_t *o, fmat_t *output, uint_t *read) { 195 aubio_source_do_multi(o->source, output, read); 196 } 197 198 #if 0 199 void 200 aubio_sampler_fetch_from_array(aubio_sampler_t *o, fvec_t *output, uint_t *read) { 201 // TODO 202 } 203 #endif 204 205 uint_t 206 aubio_sampler_get_samplerate (aubio_sampler_t *o) 207 { 208 return o->samplerate; 209 } 210 211 uint_t 212 aubio_sampler_get_opened (aubio_sampler_t *o) 213 { 214 return o->opened; //== 1 ? AUBIO_OK : AUBIO_FAIL; 215 } 216 217 uint_t 218 aubio_sampler_get_finished(aubio_sampler_t *o) 219 { 220 return o->finished; 221 } 222 223 uint_t 224 aubio_sampler_get_eof (aubio_sampler_t *o) 225 { 226 return o->eof; 227 } 228 229 uint_t 230 aubio_sampler_get_waited_opening (aubio_sampler_t *o, uint_t waited) { 231 #ifdef HAVE_THREADS 75 232 if (o->playing) { 76 aubio_source_do (o->source, o->source_output, &read); 77 for (i = 0; i < output->length; i++) { 78 output->data[i] += o->source_output->data[i]; 79 } 80 if (read < o->blocksize) o->playing = 0; 81 } 82 if (input && input != output) { 83 for (i = 0; i < output->length; i++) { 84 output->data[i] += input->data[i]; 85 } 86 } 87 } 88 89 void aubio_sampler_do_multi ( aubio_sampler_t * o, const fmat_t * input, fmat_t * output) 90 { 91 uint_t read = 0, i, j; 233 if (!o->opened) { 234 o->waited += waited; 235 } else if (o->waited) { 236 //AUBIO_WRN("sampler: waited %d frames (%.2fms) while opening %s\n", 237 // o->waited, 1000.*o->waited/(smpl_t)o->samplerate, o->uri); 238 uint_t waited = o->waited; 239 o->waited = 0; 240 return waited; 241 } 242 } 243 #endif 244 return 0; 245 } 246 247 uint_t 248 aubio_sampler_seek(aubio_sampler_t * o, uint_t pos) 249 { 250 uint_t ret = AUBIO_FAIL; 251 o->finished = 0; 252 if (!o->opened) return AUBIO_OK; 253 #ifdef HAVE_THREADS 254 if (pthread_mutex_trylock(&o->open_mutex)) { 255 AUBIO_WRN("sampler: failed locking in seek\n"); 256 return ret; 257 } 258 #endif 259 if (o->source) { 260 ret = aubio_source_seek(o->source, pos); 261 } 262 #ifdef HAVE_THREADS 263 pthread_mutex_unlock(&o->open_mutex); 264 #endif 265 return ret; 266 } 267 268 void 269 aubio_sampler_do_eof (aubio_sampler_t * o) 270 { 271 o->finished = 1; 272 o->eof = 1; 273 if (!o->loop) { 274 o->playing = 0; 275 } else { 276 aubio_sampler_seek(o, 0); 277 } 278 } 279 280 void aubio_sampler_do ( aubio_sampler_t * o, fvec_t * output, uint_t *read) 281 { 282 o->eof = 0; 283 if (o->opened == 1 && o->playing) { 284 aubio_sampler_fetch_from_source(o, output, read); 285 if (*read < o->blocksize) { 286 aubio_sampler_do_eof (o); 287 if (*read > 0) { 288 // TODO pull (hopsize - read) frames 289 //memset(... tail , 0) 290 } 291 } 292 } else { 293 fvec_zeros(output); 294 *read = 0; //output->length; 295 } 296 } 297 298 void aubio_sampler_do_multi ( aubio_sampler_t * o, fmat_t * output, uint_t *read) 299 { 300 o->eof = 0; 92 301 if (o->playing) { 93 aubio_source_do_multi (o->source, o->source_output_multi, &read); 94 for (i = 0; i < output->height; i++) { 95 for (j = 0; j < output->length; j++) { 96 output->data[i][j] += o->source_output_multi->data[i][j]; 302 aubio_sampler_fetch_from_source_multi(o, output, read); 303 if (*read < o->blocksize) { 304 aubio_sampler_do_eof (o); 305 if (*read > 0) { 306 // TODO pull (hopsize - read) frames 307 //memset(... tail , 0) 97 308 } 98 309 } 99 if ( read < o->blocksize ) o->playing = 0; 100 } 101 if (input && input != output) { 102 for (i = 0; i < output->height; i++) { 103 for (j = 0; j < output->length; j++) { 104 output->data[i][j] += input->data[i][j]; 105 } 106 } 310 } else { 311 fmat_zeros(output); 312 *read = 0; 107 313 } 108 314 } … … 119 325 } 120 326 327 uint_t aubio_sampler_get_loop ( aubio_sampler_t * o ) 328 { 329 return o->loop; 330 } 331 332 uint_t aubio_sampler_set_loop ( aubio_sampler_t * o, uint_t loop ) 333 { 334 o->loop = (loop == 1) ? 1 : 0; 335 return 0; 336 } 337 121 338 uint_t aubio_sampler_play ( aubio_sampler_t * o ) 122 339 { 123 aubio_source_seek (o->source, 0);340 //aubio_source_seek (o->source, 0); 124 341 return aubio_sampler_set_playing (o, 1); 125 342 } … … 130 347 } 131 348 349 uint_t aubio_sampler_loop ( aubio_sampler_t * o ) 350 { 351 aubio_sampler_set_loop(o, 1); 352 aubio_sampler_seek(o, 0); 353 return aubio_sampler_set_playing (o, 1); 354 } 355 356 uint_t aubio_sampler_trigger ( aubio_sampler_t * o ) 357 { 358 aubio_sampler_set_loop(o, 0); 359 aubio_sampler_seek(o, 0); 360 return aubio_sampler_set_playing (o, 1); 361 } 362 132 363 void del_aubio_sampler( aubio_sampler_t * o ) 133 364 { 365 #ifdef HAVE_THREADS 366 AUBIO_WRN("sampler: cleaning up\n"); 367 pthread_mutex_destroy(&o->open_mutex); 368 if (o->open_thread_running) { 369 if (pthread_cancel(o->open_thread)) { 370 AUBIO_WRN("sampler: cancelling open thread failed\n"); 371 } 372 } 373 void *threadret; 374 if (pthread_join(o->open_thread, &threadret)) { 375 AUBIO_WRN("sampler: joining open thread failed\n"); 376 } 377 pthread_mutex_destroy(&o->open_mutex); 378 #endif 134 379 if (o->source) { 135 380 del_aubio_source(o->source); 136 381 } 137 if (o->uri) AUBIO_FREE(o->uri);138 del_fvec(o->source_output);139 del_fmat(o->source_output_multi);140 382 AUBIO_FREE(o); 141 383 } -
src/synth/sampler.h
r923670d r88042ef 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 … … 62 67 uint_t aubio_sampler_load( aubio_sampler_t * o, const char_t * uri ); 63 68 69 /** queue source in sampler 70 71 \param o sampler, created by new_aubio_sampler() 72 \param uri the uri of the source to load 73 74 \return 0 if successfully queued, non-zero otherwise 75 76 */ 77 uint_t aubio_sampler_queue(aubio_sampler_t * o, const char_t * uri ); 78 64 79 /** process sampler function 65 80 66 81 \param o sampler, created by new_aubio_sampler() 67 \param input input of the sampler, to be added to the output68 82 \param output output of the sampler 69 83 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); 84 This function get new samples from the playing source into output. 85 86 */ 87 void aubio_sampler_do ( aubio_sampler_t * o, fvec_t * output, uint_t *read); 77 88 78 89 /** process sampler function, multiple channels 79 90 80 91 \param o sampler, created by new_aubio_sampler() 81 \param input input of the sampler, to be added to the output82 92 \param output output of the sampler 83 93 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); 94 This function gets new samples from the playing source into output. 95 96 */ 97 void aubio_sampler_do_multi ( aubio_sampler_t * o, fmat_t * output, uint_t *read); 91 98 92 99 /** get current playing state … … 109 116 uint_t aubio_sampler_set_playing ( aubio_sampler_t * o, uint_t playing ); 110 117 118 uint_t aubio_sampler_get_loop(aubio_sampler_t * o); 119 120 /** set current looping state 121 122 \param o sampler, created by new_aubio_sampler() 123 \param looping 0 for not looping, 1 for looping 124 125 \return 0 if successful, 1 otherwise 126 127 */ 128 uint_t aubio_sampler_set_loop(aubio_sampler_t * o, uint_t loop); 129 111 130 /** play sample from start 112 131 … … 118 137 uint_t aubio_sampler_play ( aubio_sampler_t * o ); 119 138 139 /** play sample from start, looping it 140 141 \param o sampler, created by new_aubio_sampler() 142 143 \return 0 if successful, 1 otherwise 144 145 */ 146 uint_t aubio_sampler_loop ( aubio_sampler_t * o ); 147 148 /** play sample from start, once 149 150 \param o sampler, created by new_aubio_sampler() 151 152 \return 0 if successful, 1 otherwise 153 154 */ 155 uint_t aubio_sampler_trigger ( aubio_sampler_t * o ); 156 120 157 /** stop sample 121 158 … … 126 163 */ 127 164 uint_t aubio_sampler_stop ( aubio_sampler_t * o ); 165 166 /** get end-of-file status 167 168 \param o sampler, created by new_aubio_sampler() 169 170 \return 1 when the eof is being reached, 0 otherwise 171 172 */ 173 uint_t aubio_sampler_get_eof(aubio_sampler_t * o); 174 175 /** get end-of-file status 176 177 \param o sampler, created by new_aubio_sampler() 178 179 \return 1 when the eof is being reached, 0 otherwise 180 181 */ 182 uint_t aubio_sampler_get_finished (aubio_sampler_t * o); 183 184 /** get samplerate 185 186 \param o sampler, created by new_aubio_sampler() 187 188 \return samplerate of the sampler 189 190 */ 191 uint_t aubio_sampler_get_samplerate(aubio_sampler_t * o); 192 193 /** get the number of samples that were set to zero while opening a file 194 195 \param o sampler, created by new_aubio_sampler() 196 197 \return samplerate of the sampler 198 199 */ 200 uint_t aubio_sampler_get_waited_opening(aubio_sampler_t * o, uint_t waited); 201 202 /** seek to position 203 204 \param o sampler, created by new_aubio_sampler() 205 \param pos position to seek to, in samples 206 207 \return 0 if successful, 1 otherwise 208 209 */ 210 uint_t aubio_sampler_seek(aubio_sampler_t * o, uint_t pos); 128 211 129 212 /** destroy ::aubio_sampler_t object
Note: See TracChangeset
for help on using the changeset viewer.