1 // audio.c
2 // LiVES (lives-exe)
3 // (c) G. Finch 2005 - 2020
4 // Released under the GPL 3 or later
5 // see file ../COPYING for licensing details
6
7 #include "main.h"
8 #include "audio.h"
9 #include "events.h"
10 #include "callbacks.h"
11 #include "effects.h"
12 #include "resample.h"
13
14 static char *storedfnames[NSTOREDFDS];
15 static int storedfds[NSTOREDFDS];
16 static boolean storedfdsset = FALSE;
17
18
audio_reset_stored_fnames(void)19 static void audio_reset_stored_fnames(void) {
20 for (int i = 0; i < NSTOREDFDS; i++) {
21 storedfnames[i] = NULL;
22 storedfds[i] = -1;
23 }
24 storedfdsset = TRUE;
25 }
26
27
get_achannel_name(int totchans,int idx)28 LIVES_GLOBAL_INLINE char *get_achannel_name(int totchans, int idx) {
29 if (totchans == 1) return (_("Mono"));
30 if (totchans == 2) {
31 if (idx == 0) return (_("Left channel"));
32 if (idx == 1) return (_("Right channel"));
33 }
34 return lives_strdup_printf(_("Audio channel %d"), idx);
35 }
36
37
get_audio_file_name(int fnum,boolean opening)38 LIVES_GLOBAL_INLINE char *get_audio_file_name(int fnum, boolean opening) {
39 char *fname;
40 if (!opening) {
41 if (IS_VALID_CLIP(fnum))
42 fname = lives_build_filename(prefs->workdir, mainw->files[fnum]->handle, CLIP_AUDIO_FILENAME, NULL);
43 else
44 fname = lives_build_filename(prefs->workdir, CLIP_AUDIO_FILENAME, NULL);
45 } else {
46 if (IS_VALID_CLIP(fnum))
47 fname = lives_build_filename(prefs->workdir, mainw->files[fnum]->handle, CLIP_TEMP_AUDIO_FILENAME, NULL);
48 else
49 fname = lives_build_filename(prefs->workdir, CLIP_TEMP_AUDIO_FILENAME, NULL);
50 }
51 return fname;
52 }
53
54
lives_get_audio_file_name(int fnum)55 LIVES_GLOBAL_INLINE char *lives_get_audio_file_name(int fnum) {
56 char *fname = get_audio_file_name(fnum, FALSE);
57 if (mainw->files[fnum]->opening && !lives_file_test(fname, LIVES_FILE_TEST_EXISTS)) {
58 lives_free(fname);
59 fname = get_audio_file_name(fnum, TRUE);
60 }
61 return fname;
62 }
63
64
audio_player_get_display_name(const char * aplayer)65 LIVES_GLOBAL_INLINE const char *audio_player_get_display_name(const char *aplayer) {
66 if (!strcmp(aplayer, AUDIO_PLAYER_PULSE)) return AUDIO_PLAYER_PULSE_AUDIO;
67 return aplayer;
68 }
69
70
audio_free_fnames(void)71 void audio_free_fnames(void) {
72 // cleanup stored filehandles after playback/fade/render
73 if (!storedfdsset) return;
74 for (int i = 0; i < NSTOREDFDS; i++) {
75 lives_freep((void **)&storedfnames[i]);
76 if (storedfds[i] > -1) lives_close_buffered(storedfds[i]);
77 storedfds[i] = -1;
78 }
79 }
80
81
append_to_audio_bufferf(float * src,uint64_t nsamples,int channum)82 void append_to_audio_bufferf(float *src, uint64_t nsamples, int channum) {
83 // append float audio to the audio frame buffer
84 size_t nsampsize;
85 lives_audio_buf_t *abuf;
86
87 if (!prefs->push_audio_to_gens) return;
88
89 pthread_mutex_lock(&mainw->abuf_frame_mutex);
90
91 abuf = (lives_audio_buf_t *)mainw->audio_frame_buffer; // this is a pointer to either mainw->afb[0] or mainw->afb[1]
92
93 if (!abuf) {
94 pthread_mutex_unlock(&mainw->abuf_frame_mutex);
95 return;
96 }
97
98 if (!abuf->bufferf) free_audio_frame_buffer(abuf);
99
100 nsampsize = (abuf->samples_filled + nsamples);
101
102 channum++;
103 if (channum > abuf->out_achans) {
104 int i;
105 abuf->bufferf = (float **)lives_realloc(abuf->bufferf, channum * sizeof(float *));
106 for (i = abuf->out_achans; i < channum; i++) {
107 abuf->bufferf[i] = NULL;
108 }
109 abuf->out_achans = channum;
110 }
111 channum--;
112 abuf->bufferf[channum] = (float *)lives_realloc(abuf->bufferf[channum], nsampsize * sizeof(float) + EXTRA_BYTES);
113 lives_memcpy(&abuf->bufferf[channum][abuf->samples_filled], src, nsamples * sizeof(float));
114 pthread_mutex_unlock(&mainw->abuf_frame_mutex);
115 }
116
117
append_to_audio_buffer16(void * src,uint64_t nsamples,int channum)118 void append_to_audio_buffer16(void *src, uint64_t nsamples, int channum) {
119 // append 16 bit audio to the audio frame buffer
120 size_t nsampsize;
121 lives_audio_buf_t *abuf;
122
123 if (!prefs->push_audio_to_gens) return;
124
125 pthread_mutex_lock(&mainw->abuf_frame_mutex);
126
127 abuf = (lives_audio_buf_t *)mainw->audio_frame_buffer; // this is a pointer to either mainw->afb[0] or mainw->afb[1]
128
129 if (!abuf) {
130 pthread_mutex_unlock(&mainw->abuf_frame_mutex);
131 return;
132 }
133 if (!abuf->buffer16) free_audio_frame_buffer(abuf);
134
135 nsampsize = (abuf->samples_filled + nsamples);
136 channum++;
137 if (!abuf->buffer16 || channum > abuf->out_achans) {
138 int i;
139 abuf->buffer16 = (int16_t **)lives_calloc(channum, sizeof(short *));
140 for (i = abuf->out_achans; i < channum; i++) {
141 abuf->buffer16[i] = NULL;
142 }
143 abuf->out_achans = channum;
144 }
145 channum--;
146 abuf->buffer16[channum] = (short *)lives_realloc(abuf->buffer16[channum], nsampsize * sizeof(short) + EXTRA_BYTES);
147 lives_memcpy(&abuf->buffer16[channum][abuf->samples_filled], src, nsamples * 2);
148 #ifdef DEBUG_AFB
149 g_print("append16 to afb\n");
150 #endif
151 pthread_mutex_unlock(&mainw->abuf_frame_mutex);
152 }
153
154
init_audio_frame_buffers(short aplayer)155 void init_audio_frame_buffers(short aplayer) {
156 // function should be called when the first video generator with audio input is enabled
157 int i;
158
159 for (i = 0; i < 2; i++) {
160 lives_audio_buf_t *abuf;
161 mainw->afb[i] = abuf = (lives_audio_buf_t *)lives_calloc(1, sizeof(lives_audio_buf_t));
162
163 abuf->samples_filled = 0;
164 abuf->swap_endian = FALSE;
165 abuf->out_achans = 0;
166 abuf->start_sample = 0;
167
168 switch (aplayer) {
169 #ifdef HAVE_PULSE_AUDIO
170 case AUD_PLAYER_PULSE:
171 abuf->in_interleaf = abuf->out_interleaf = TRUE;
172 abuf->s16_signed = TRUE;
173 if (mainw->pulsed_read) {
174 abuf->in_achans = abuf->out_achans = mainw->pulsed_read->in_achans;
175 abuf->arate = mainw->pulsed_read->in_arate;
176 } else if (mainw->pulsed) {
177 abuf->in_achans = abuf->out_achans = mainw->pulsed->out_achans;
178 abuf->arate = mainw->pulsed->out_arate;
179 }
180 break;
181 #endif
182 #ifdef ENABLE_JACK
183 case AUD_PLAYER_JACK:
184 abuf->in_interleaf = abuf->out_interleaf = FALSE;
185 if (mainw->jackd_read && mainw->jackd_read->in_use) {
186 abuf->in_achans = abuf->out_achans = mainw->jackd_read->num_input_channels;
187 abuf->arate = mainw->jackd_read->sample_in_rate;
188 } else if (mainw->jackd) {
189 abuf->in_achans = abuf->out_achans = mainw->jackd->num_output_channels;
190 abuf->arate = mainw->jackd->sample_out_rate;
191 }
192 break;
193 #endif
194 default:
195 break;
196 }
197 }
198
199 mainw->audio_frame_buffer = mainw->afb[0];
200
201 #ifdef DEBUG_AFB
202 g_print("init afb\n");
203 #endif
204 }
205
206
free_audio_frame_buffer(lives_audio_buf_t * abuf)207 void free_audio_frame_buffer(lives_audio_buf_t *abuf) {
208 // function should be called to clear samples
209 // cannot use lives_freep
210 int i;
211 if (abuf) {
212 if (abuf->bufferf) {
213 for (i = 0; i < abuf->out_achans; i++) lives_free(abuf->bufferf[i]);
214 lives_free(abuf->bufferf);
215 abuf->bufferf = NULL;
216 }
217 if (abuf->buffer32) {
218 for (i = 0; i < abuf->out_achans; i++) lives_free(abuf->buffer32[i]);
219 lives_free(abuf->buffer32);
220 abuf->buffer32 = NULL;
221 }
222 if (abuf->buffer24) {
223 for (i = 0; i < abuf->out_achans; i++) lives_free(abuf->buffer24[i]);
224 lives_free(abuf->buffer24);
225 abuf->buffer24 = NULL;
226 }
227 if (abuf->buffer16) {
228 for (i = 0; i < abuf->out_achans; i++) lives_free(abuf->buffer16[i]);
229 lives_free(abuf->buffer16);
230 abuf->buffer16 = NULL;
231 }
232 if (abuf->buffer8) {
233 for (i = 0; i < abuf->out_achans; i++) lives_free(abuf->buffer8[i]);
234 lives_free(abuf->buffer8);
235 abuf->buffer8 = NULL;
236 }
237
238 abuf->samples_filled = 0;
239 abuf->out_achans = 0;
240 abuf->start_sample = 0;
241 }
242 #ifdef DEBUG_AFB
243 g_print("clear afb %p\n", abuf);
244 #endif
245 }
246
247
audiofile_get_maxvol(int fnum,double start,double end,float thresh)248 float audiofile_get_maxvol(int fnum, double start, double end, float thresh) {
249 if (!IS_NORMAL_CLIP(fnum) || !mainw->files[fnum]->achans || start >= mainw->files[fnum]->laudio_time) return -1.;
250 else {
251 double atime = start;
252 lives_clip_t *afile = mainw->files[fnum];
253 char *filename = lives_get_audio_file_name(mainw->current_file);
254 int afd = lives_open_buffered_rdonly(filename);
255 float xx = 0., xf;
256 int c;
257 lives_free(filename);
258 if (end == 0. || end > afile->laudio_time) end = afile->laudio_time;
259 while (atime <= end) {
260 for (c = 0; c < afile->achans; c++) {
261 if (afd == -1) {
262 THREADVAR(read_failed) = -2;
263 return -1.;
264 }
265 xf = fabsf(get_float_audio_val_at_time(fnum, afd, atime, c, afile->achans));
266 if (xf > xx) xx = xf;
267 if (thresh >= 0. && xx > thresh) {
268 lives_close_buffered(afd);
269 return xx;
270 }
271 }
272 atime += 1. / afile->arps;
273 }
274 lives_close_buffered(afd);
275 return xx;
276 }
277 }
278
279
normalise_audio(int fnum,double start,double end,float thresh)280 boolean normalise_audio(int fnum, double start, double end, float thresh) {
281 if (!IS_NORMAL_CLIP(fnum)) return FALSE;
282 else {
283 float xx = audiofile_get_maxvol(fnum, start, end, -1.);
284 if (xx <= 0.) return FALSE;
285 if (1) {
286 lives_clip_t *afile = mainw->files[fnum];
287 double atime = start;
288 float fact = thresh / xx, val;
289 char *filename = lives_get_audio_file_name(mainw->current_file);
290 boolean xsigned = !(afile->signed_endian & AFORM_UNSIGNED);
291 boolean swap_endian = FALSE;
292 int afd, afd2;
293 int c, count = 0;
294
295 THREADVAR(read_failed) = THREADVAR(write_failed) = 0;
296 threaded_dialog_spin(0.);
297
298 afd = lives_open_buffered_rdonly(filename);
299 if (afd == -1) {
300 lives_free(filename);
301 THREADVAR(read_failed) = -2;
302 return FALSE;
303 }
304 afd2 = lives_open_buffered_writer(filename, capable->umask, TRUE);
305 if (afd2 == -1) {
306 lives_close_buffered(afd);
307 lives_free(filename);
308 THREADVAR(write_failed) = -2;
309 return FALSE;
310 }
311 lives_free(filename);
312
313 if (((afile->signed_endian & AFORM_BIG_ENDIAN) && capable->byte_order == LIVES_LITTLE_ENDIAN)
314 || ((afile->signed_endian & AFORM_LITTLE_ENDIAN) && capable->byte_order == LIVES_BIG_ENDIAN))
315 swap_endian = TRUE;
316
317 lives_lseek_buffered_writer(afd2, quant_abytes(start, afile->arps, afile->achans, afile->asampsize));
318 threaded_dialog_spin(0.);
319
320 if (end == 0. || end > afile->laudio_time) end = afile->laudio_time;
321 while (atime <= end) {
322 if (mainw->cancelled != CANCEL_NONE) break;
323 if (count == afile->arps) count = 0;
324 if (!count++) threaded_dialog_spin((atime - start) / (end - start));
325 for (c = 0; c < afile->achans; c++) {
326 xx = get_float_audio_val_at_time(fnum, afd, atime, c, afile->achans) * fact;
327 if (THREADVAR(read_failed)) break;
328 if (afile->asampsize == 8) {
329 if (!xsigned) {
330 uint8_t ucval;
331 val = xx * 127.4999 + 127.4999;
332 ucval = (uint8_t)(127.4999 * xx) + 127.4999;
333 lives_write_buffered(afd2, (const char *)&ucval, 1, FALSE);
334 } else {
335 char scval;
336 val = xx * 255.499;
337 scval = (char)(255.499 * xx - 128.);
338 lives_write_buffered(afd2, &scval, 1, FALSE);
339 }
340 } else {
341 if (!xsigned) {
342 uint16_t usval;
343 val = xx * SAMPLE_MAX_16BIT_P + SAMPLE_MAX_16BIT_P;
344 usval = (val > 65535 ? 65535 : val < 0 ? 0 : val);
345 if (swap_endian) swab2(&usval, &usval, 1);
346 lives_write_buffered(afd2, (const char *)&usval, 2, FALSE);
347 } else {
348 float val = xx * SAMPLE_MAX_16BIT_P;
349 int16_t ssval = (int16_t)(val > SAMPLE_MAX_16BIT_P ? SAMPLE_MAX_16BIT_P
350 : val < -SAMPLE_MAX_16BIT_N ? -SAMPLE_MAX_16BIT_N : val);
351 if (swap_endian) swab2(&ssval, &ssval, 1);
352 lives_write_buffered(afd2, (const char *)(&ssval), 2, FALSE);
353 }
354 }
355 if (THREADVAR(write_failed)) break;
356 }
357 if (THREADVAR(read_failed) || THREADVAR(write_failed)) {
358 THREADVAR(read_failed) = THREADVAR(write_failed) = 0;
359 break;
360 }
361 atime += 1. / afile->arps;
362 }
363 lives_close_buffered(afd);
364 lives_close_buffered(afd2);
365 }
366 if (mainw->cancelled != CANCEL_NONE || THREADVAR(read_failed) || THREADVAR(write_failed)) {
367 return FALSE;
368 }
369 return TRUE;
370 }
371 }
372
373
get_float_audio_val_at_time(int fnum,int afd,double secs,int chnum,int chans)374 float get_float_audio_val_at_time(int fnum, int afd, double secs, int chnum, int chans) {
375 // return audio level between -1.0 and +1.0
376 // afd must be opened with lives_open_buffered_rdonly()
377 lives_clip_t *afile = mainw->files[fnum];
378 off_t apos;
379 uint8_t val8, val8b;
380 uint16_t val16;
381 float val;
382 size_t quant = afile->achans * afile->asampsize / 8;
383 size_t bytes = (size_t)(secs * (double)afile->arate) * quant;
384
385 if (!bytes) return 0.;
386
387 apos = ((size_t)(bytes / quant) * quant); // quantise
388
389 apos += afile->asampsize / 8 * chnum;
390 lives_lseek_buffered_rdonly_absolute(afd, apos);
391
392 if (afile->asampsize == 8) {
393 // 8 bit sample size
394 if (!lives_read_buffered(afd, &val8, 1, TRUE)) return 0.;
395 if (!(afile->signed_endian & AFORM_UNSIGNED)) val = val8 >= 128 ? val8 - 256 : val8;
396 else val = val8 - 127;
397 if (val > 0.) val /= 127.;
398 else val /= 128.;
399 } else {
400 // 16 bit sample size
401 if (!lives_read_buffered(afd, &val8, 1, TRUE) || !lives_read_buffered(afd, &val8b, 1, TRUE)) return 0.;
402 if (afile->signed_endian & AFORM_BIG_ENDIAN) val16 = (uint16_t)(val8 << 8) + val8b;
403 else val16 = (uint16_t)(val8b << 8) + val8;
404 if (!(afile->signed_endian & AFORM_UNSIGNED)) val = (val16 >= 32768 ? val16 - 65536 : val16);
405 else val = val16 - 32767;
406 if (val > 0.) val /= 32767.;
407 else val /= 32768.;
408
409 }
410 //printf("val is %f\n",val);
411 return val;
412 }
413
414
sample_silence_dS(float * dst,uint64_t nsamples)415 LIVES_GLOBAL_INLINE void sample_silence_dS(float *dst, uint64_t nsamples) {
416 // send silence to the jack player
417 lives_memset(dst, 0, nsamples * sizeof(float));
418 }
419
420
sample_silence_stream(int nchans,int64_t nframes)421 void sample_silence_stream(int nchans, int64_t nframes) {
422 float **fbuff = (float **)lives_calloc(nchans, sizeof(float *));
423 boolean memok = TRUE;
424 int i;
425
426 for (i = 0; i < nchans; i++) {
427 fbuff[i] = (float *)lives_calloc(nframes, sizeof(float));
428 if (!fbuff[i]) memok = FALSE;
429 }
430 if (memok) {
431 pthread_mutex_lock(&mainw->vpp_stream_mutex);
432 if (mainw->ext_audio && mainw->vpp && mainw->vpp->render_audio_frame_float) {
433 (*mainw->vpp->render_audio_frame_float)(fbuff, nframes);
434 }
435 pthread_mutex_unlock(&mainw->vpp_stream_mutex);
436 }
437 for (i = 0; i < nchans; i++) {
438 lives_freep((void **)&fbuff[i]);
439 }
440 free(fbuff);
441 }
442
443
444 /* //void normalise(float rms) */
445 /* if (i == 0) { */
446 /* int dlen = weed_layer_get_audio_length(layer); */
447 /* for (ch =0; ch < achans; ch++) { */
448 /* for (smp = 0; smp < dlen; smp ++) { */
449 /* avg += adata[ch][smp]; */
450 /* } */
451 /* avg /= dlen; */
452 /* for (smp = 0; smp < dlen; smp ++) { */
453 /* avg += adata[ch][smp]; */
454 /* } */
455 /* }}} */
456
457
458 // TODO: going from >1 channels to 1, we should average
sample_move_d8_d16(short * dst,uint8_t * src,uint64_t nsamples,size_t tbytes,double scale,int nDstChannels,int nSrcChannels,int swap_sign)459 void sample_move_d8_d16(short *dst, uint8_t *src,
460 uint64_t nsamples, size_t tbytes, double scale,
461 int nDstChannels, int nSrcChannels, int swap_sign) {
462 // convert 8 bit audio to 16 bit audio
463
464 // endianess will be machine endian
465 static double rem = 0.f;
466 double src_offset_d = rem;
467 unsigned char *ptr;
468 unsigned char *src_end;
469 off_t src_offset_i = 0;
470 int ccount;
471 int nSrcCount, nDstCount;
472
473 // take care of rounding errors
474 src_end = src + tbytes - nSrcChannels;
475
476 if (!nSrcChannels) return;
477
478 if (scale < 0.f) {
479 src_offset_d = ((double)nsamples * (-scale) - 1.f - rem);
480 src_offset_i = (off_t)src_offset_d * nSrcChannels;
481 }
482
483 while (nsamples--) {
484 nSrcCount = nSrcChannels;
485 nDstCount = nDstChannels;
486 ccount = 0;
487
488 /* loop until all of our destination channels are filled */
489 while (nDstCount) {
490 nSrcCount--;
491 nDstCount--;
492
493 ptr = src + ccount + src_offset_i;
494 ptr = ptr > src ? (ptr < (src_end + ccount) ? ptr : (src_end + ccount)) : src;
495
496 if (!swap_sign) *(dst++) = *(ptr) << 8;
497 else if (swap_sign == SWAP_U_TO_S) *(dst++) = ((short)(*(ptr)) - 128) << 8;
498 else *((unsigned short *)(dst++)) = ((short)(*(ptr)) + 128) << 8;
499 ccount++;
500
501 /* if we ran out of source channels but not destination channels */
502 /* then start the src channels back where we were */
503 if (!nSrcCount && nDstCount) {
504 ccount = 0;
505 nSrcCount = nSrcChannels;
506 }
507 }
508
509 /* advance the position */
510 src_offset_i = (off_t)((src_offset_d += scale) + .4999) * nSrcChannels;
511 }
512 rem = 0.f;
513 if (scale > 0.f) {
514 if (src_offset_d > src_offset_i) rem = src_offset_d - (double)src_offset_i;
515 } else {
516 if (src_offset_d < src_offset_i) rem = (double)src_offset_i - src_offset_d;
517 }
518 }
519
520
521 /**
522 @brief convert from any number of source channels to any number of destination channels - both interleaved
523 */
sample_move_d16_d16(int16_t * dst,int16_t * src,uint64_t nsamples,size_t tbytes,double scale,int nDstChannels,int nSrcChannels,int swap_endian,int swap_sign)524 void sample_move_d16_d16(int16_t *dst, int16_t *src,
525 uint64_t nsamples, size_t tbytes, double scale, int nDstChannels,
526 int nSrcChannels, int swap_endian, int swap_sign) {
527 // TODO: going from >1 channels to 1, we should average
528 static double rem = 0.f;
529 double src_offset_d = rem;
530 int16_t *ptr;
531 int16_t *src_end;
532 int nSrcCount, nDstCount;
533 off_t src_offset_i = 0;
534 int ccount = 0;
535
536 if (!nSrcChannels) return;
537
538 if (scale < 0.f) {
539 src_offset_d = ((double)nsamples * (-scale) - 1.f - rem);
540 src_offset_i = (off_t)src_offset_d * nSrcChannels;
541 }
542
543 // take care of rounding errors
544 src_end = src + tbytes / 2 - nSrcChannels;
545
546 if ((off_t)((fabs(scale) * (double)nsamples) + rem) * nSrcChannels * 2 > tbytes)
547 scale = scale > 0. ? ((double)(tbytes / nSrcChannels / 2) - rem) / (double)nsamples
548 : -(((double)(tbytes / nSrcChannels / 2) - rem) / (double)nsamples);
549
550 while (nsamples--) {
551 if ((nSrcCount = nSrcChannels) == (nDstCount = nDstChannels) && !swap_endian && !swap_sign) {
552 // same number of channels
553
554 if (scale == 1.f) {
555 lives_memcpy((void *)dst, (void *)src, nsamples * 2 * nSrcChannels);
556 return;
557 }
558
559 ptr = src + src_offset_i;
560 ptr = ptr > src ? (ptr < src_end ? ptr : src_end) : src;
561 lives_memcpy(dst, ptr, nSrcChannels * 2);
562 dst += nDstCount;
563 } else {
564 ccount = 0;
565
566 /* loop until all of our destination channels are filled */
567 while (nDstCount) {
568 nSrcCount--;
569 nDstCount--;
570
571 ptr = src + ccount + src_offset_i;
572 ptr = ptr > src ? (ptr < (src_end + ccount) ? ptr : (src_end + ccount)) : src;
573
574 /* copy the data over */
575 if (!swap_endian) {
576 if (!swap_sign) *(dst++) = *ptr;
577 else if (swap_sign == SWAP_S_TO_U) *((uint16_t *)dst++) = (uint16_t)(*ptr + SAMPLE_MAX_16BITI);
578 else *(dst++) = *ptr - SAMPLE_MAX_16BITI;
579 } else if (swap_endian == SWAP_X_TO_L) {
580 if (!swap_sign) *(dst++) = (((*ptr) & 0x00FF) << 8) + ((*ptr) >> 8);
581 else if (swap_sign == SWAP_S_TO_U) *((uint16_t *)dst++) = (uint16_t)(((*ptr & 0x00FF) << 8) + (*ptr >> 8)
582 + SAMPLE_MAX_16BITI);
583 else *(dst++) = ((*ptr & 0x00FF) << 8) + (*ptr >> 8) - SAMPLE_MAX_16BITI;
584 } else {
585 if (!swap_sign) *(dst++) = (((*ptr) & 0x00FF) << 8) + ((*ptr) >> 8);
586 else if (swap_sign == SWAP_S_TO_U) *((uint16_t *)dst++) =
587 (uint16_t)(((((uint16_t)(*ptr + SAMPLE_MAX_16BITI)) & 0x00FF) << 8) +
588 (((uint16_t)(*ptr + SAMPLE_MAX_16BITI)) >> 8));
589 else *(dst++) = ((((int16_t)(*ptr - SAMPLE_MAX_16BITI)) & 0x00FF) << 8) + (((int16_t)(*ptr - SAMPLE_MAX_16BITI)) >> 8);
590 }
591
592 ccount++;
593
594 /* if we ran out of source channels but not destination channels */
595 /* then start the src channels back where we were */
596 if (!nSrcCount && nDstCount) {
597 ccount = 0;
598 nSrcCount = nSrcChannels;
599 }
600 }
601 }
602 /* advance the position */
603 src_offset_i = (off_t)((src_offset_d += scale) + .4999) * nSrcChannels;
604 }
605 rem = 0.f;
606 if (scale > 0.f) {
607 if (src_offset_d > src_offset_i) rem = src_offset_d - (double)src_offset_i;
608 } else {
609 if (src_offset_d < src_offset_i) rem = (double)src_offset_i - src_offset_d;
610 }
611 }
612
613
614 /**
615 @brief convert from any number of source channels to any number of destination channels - 8 bit output
616 */
sample_move_d16_d8(uint8_t * dst,short * src,uint64_t nsamples,size_t tbytes,double scale,int nDstChannels,int nSrcChannels,int swap_sign)617 void sample_move_d16_d8(uint8_t *dst, short *src,
618 uint64_t nsamples, size_t tbytes, double scale, int nDstChannels, int nSrcChannels, int swap_sign) {
619 // TODO: going from >1 channels to 1, we should average
620 double rem = 0.f;
621 double src_offset_d = rem;
622 short *ptr;
623 short *src_end;
624 off_t src_offset_i = 0;
625 int ccount = 0;
626 int nSrcCount, nDstCount;
627
628 if (!nSrcChannels) return;
629
630 if (scale < 0.f) {
631 src_offset_d = ((double)nsamples * (-scale) - 1.f - rem);
632 src_offset_i = (off_t)src_offset_d * nSrcChannels;
633 }
634
635 src_end = src + tbytes / sizeof(short) - nSrcChannels;
636
637 while (nsamples--) {
638 nSrcCount = nSrcChannels;
639 nDstCount = nDstChannels;
640
641 ccount = 0;
642
643 /* loop until all of our destination channels are filled */
644 while (nDstCount) {
645 nSrcCount--;
646 nDstCount--;
647
648 ptr = src + ccount + src_offset_i;
649 ptr = ptr > src ? (ptr < (src_end + ccount) ? ptr : src_end + ccount) : src;
650
651 /* copy the data over */
652 if (!swap_sign) *(dst++) = (*ptr >> 8);
653 else if (swap_sign == SWAP_S_TO_U) *(dst++) = (uint8_t)((int8_t)(*ptr >> 8) + 128);
654 else *((int8_t *)dst++) = (int8_t)((uint8_t)(*ptr >> 8) - 128);
655 ccount++;
656
657 /* if we ran out of source channels but not destination channels */
658 /* then start the src channels back where we were */
659 if (!nSrcCount && nDstCount) {
660 ccount = 0;
661 nSrcCount = nSrcChannels;
662 }
663 }
664
665 /* advance the position */
666 src_offset_i = (off_t)((src_offset_d += scale) + .4999) * nSrcChannels;
667 }
668 rem = 0.f;
669 if (scale > 0.f) {
670 if (src_offset_d > src_offset_i) rem = src_offset_d - (double)src_offset_i;
671 } else {
672 if (src_offset_d < src_offset_i) rem = (double)src_offset_i - src_offset_d;
673 }
674 }
675
676
sample_move_d16_float(float * dst,short * src,uint64_t nsamples,uint64_t src_skip,int is_unsigned,boolean rev_endian,float vol)677 float sample_move_d16_float(float *dst, short *src, uint64_t nsamples, uint64_t src_skip, int is_unsigned, boolean rev_endian,
678 float vol) {
679 // convert 16 bit audio to float audio
680
681 // returns abs(maxvol heard)
682
683 float svolp, svoln;
684
685 #ifdef ENABLE_OIL
686 float val = 0.; // set a value to stop valgrind complaining
687 float maxval = 0.;
688 double xn, xp, xa;
689 double y = 0.f;
690 #else
691 float val;
692 float maxval = 0.;
693 short valss;
694 #endif
695
696 uint8_t srcx[2];
697 short srcxs;
698 short *srcp;
699
700 if (vol == 0.) vol = 0.0000001f;
701 svolp = SAMPLE_MAX_16BIT_P / vol;
702 svoln = SAMPLE_MAX_16BIT_N / vol;
703
704 #ifdef ENABLE_OIL
705 xp = 1. / svolp;
706 xn = 1. / svoln;
707 xa = 2. * vol / (SAMPLE_MAX_16BIT_P + SAMPLE_MAX_16BIT_N);
708 #endif
709
710 while (nsamples--) { // valgrind
711 if (rev_endian) {
712 lives_memcpy(&srcx, src, 2);
713 srcxs = ((srcx[1] & 0xFF) << 8) + (srcx[0] & 0xFF);
714 srcp = &srcxs;
715 } else srcp = src;
716
717 if (!is_unsigned) {
718 #ifdef ENABLE_OIL
719 oil_scaleconv_f32_s16(&val, srcp, 1, &y, val > 0 ? &xp : &xn);
720 #else
721 if ((val = (float)((float)(*srcp) / (*srcp > 0 ? svolp : svoln))) > 1.0f) val = 1.0f;
722 else if (val < -1.0f) val = -1.0f;
723 #endif
724 } else {
725 #ifdef ENABLE_OIL
726 oil_scaleconv_f32_u16(&val, (unsigned short *)srcp, 1, &y, &xa);
727 val -= vol;
728 #else
729 valss = (unsigned short) * srcp - SAMPLE_MAX_16BITI;
730 if ((val = (float)((float)(valss) / (valss > 0 ? svolp : svoln))) > 1.0f) val = 1.0f;
731 else if (val < -1.0f) val = -1.0f;
732 #endif
733 }
734
735 if (val > maxval) maxval = val;
736 else if (-val > maxval) maxval = -val;
737
738 *(dst++) = val;
739 src += src_skip;
740 }
741 return maxval;
742 }
743
744
sample_move_float_float(float * dst,float * src,uint64_t nsamples,double scale,int dst_skip)745 void sample_move_float_float(float *dst, float *src, uint64_t nsamples, double scale, int dst_skip) {
746 // copy one channel of float to a buffer, applying the scale (scale 2.0 to double the rate, etc)
747 static double rem = 0.f;
748 double offs_d = rem;
749 off_t offs = 0;
750 int i;
751
752 if (scale < 0.f) {
753 offs_d = ((double)nsamples * (-scale) - 1.f - rem);
754 offs = (off_t)offs_d;
755 }
756
757 if (scale == 1.f && dst_skip == 1) {
758 lives_memcpy((void *)dst, (void *)src, nsamples * sizeof(float));
759 return;
760 }
761
762 for (i = 0; i < nsamples; i++) {
763 *dst = src[offs];
764 dst += dst_skip;
765 offs = (off_t)((offs_d += scale) + .4999);
766 }
767 rem = 0.f;
768 if (scale > 0.f) {
769 if (offs_d > offs) rem = offs_d - (double)offs;
770 } else {
771 if (offs_d < offs) rem = (double)offs - offs_d;
772 }
773 }
774
775
776 #define CLIP_DECAY ((double)16535. / (double)16536.)
777
778 /**
779 @brief convert float samples back to int
780 interleaved is for the float buffer; output int is always interleaved
781 scale is out_sample_rate / in_sample_rate (so 2.0 would play twice as fast, etc.)
782 nsamps is number of out samples, asamps is out sample bit size (8 or 16)
783 output is in holding_buff which can be cast to uint8_t *, int16_t *, or uint16_t *
784 returns number of frames out
785
786 clipping is applied so that -1.0 <= fval <= 1.0
787 the clipping value is applied linearly to vol (as a divisor), and if not reset it will decay so
788 clip = 1.0 + (clip - 1.0) * CLIP_DECAY each sample
789 --> clip = 1.0 + clip * CLIP_DECAY - CLIP_DECAY
790 --> clip = (clip * CLIP_DECAY) + (1.0 - CLIP_DECAY)
791 --> clip *= CLIP_DECAY; clip += (1.0 - CLIP_DECAY)
792 */
sample_move_float_int(void * holding_buff,float ** float_buffer,int nsamps,double scale,int chans,int asamps,int usigned,boolean rev_endian,boolean interleaved,float vol)793 int64_t sample_move_float_int(void *holding_buff, float **float_buffer, int nsamps, double scale, int chans, int asamps,
794 int usigned, boolean rev_endian, boolean interleaved, float vol) {
795 int64_t frames_out = 0l;
796 int i;
797 off_t offs = 0, coffs = 0, lcoffs = -1;
798
799 static double coffs_d = 0.f;
800 const double add = (1.0 - CLIP_DECAY);
801
802 short *hbuffs = (short *)holding_buff;
803 unsigned short *hbuffu = (unsigned short *)holding_buff;
804 unsigned char *hbuffc = (unsigned char *)holding_buff;
805 short val[chans];
806 unsigned short valu[chans];
807 static float clip = 1.0;
808 float ovalf[chans], valf[chans], fval;
809 float volx = vol, ovolx = -1.;
810 boolean checklim = FALSE;
811
812 asamps >>= 3;
813
814 if (clip > 1.0) checklim = TRUE;
815
816 while ((nsamps - frames_out) > 0) {
817 frames_out++;
818 if (checklim) {
819 if (clip > 1.0) {
820 clip = clip * CLIP_DECAY + add;
821 volx = vol / clip;
822 } else {
823 checklim = FALSE;
824 clip = 1.0;
825 volx = vol;
826 }
827 }
828
829 for (i = 0; i < chans; i++) {
830 if (coffs != lcoffs) {
831 if ((fval = fabsf((ovalf[i] = *(float_buffer[i] + (interleaved ? (coffs * chans) : coffs))))) > clip) {
832 clip = fval;
833 checklim = TRUE;
834 volx = (vol / clip);
835 i = -1;
836 continue;
837 }
838 }
839 if (volx != ovolx || coffs != lcoffs) {
840 valf[i] = ovalf[i] * volx;
841 if (valf[i] > vol) valf[i] = vol;
842 else if (valf[i] < -vol) valf[i] = -vol;
843 ovolx = volx;
844 val[i] = (short)(valf[i] * (valf[i] > 0. ? SAMPLE_MAX_16BIT_P : SAMPLE_MAX_16BIT_N));
845 if (usigned) valu[i] = (val[i] + SAMPLE_MAX_16BITI);
846 }
847
848 if (asamps == 2) {
849 if (!rev_endian) {
850 if (usigned) *(hbuffu + offs) = valu[i];
851 else *(hbuffs + offs) = val[i];
852 } else {
853 if (usigned) {
854 *(hbuffc + offs) = valu[i] & 0x00FF;
855 *(hbuffc + (++offs)) = (valu[i] & 0xFF00) >> 8;
856 } else {
857 *(hbuffc + offs) = val[i] & 0x00FF;
858 *(hbuffc + (++offs)) = (val[i] & 0xFF00) >> 8;
859 }
860 }
861 } else {
862 *(hbuffc + offs) = (unsigned char)(valu[i] >> 8);
863 }
864 offs++;
865 }
866 lcoffs = coffs;
867 coffs = (off_t)((coffs_d += scale) + .4999);
868 }
869 coffs_d -= (double)coffs;
870 if (prefs->show_dev_opts) {
871 if (frames_out != nsamps) {
872 char *msg = lives_strdup_printf("audio float -> int: buffer mismatch of %ld samples\n", frames_out - nsamps);
873 LIVES_WARN(msg);
874 lives_free(msg);
875 }
876 }
877 return frames_out;
878 }
879
880
881 // play from memory buffer
882
883 /**
884 @brief copy audio data from cache into audio sound buffer
885 - float32 version (e.g. jack)
886 nchans, nsamps. out_arate all refer to player values
887 */
sample_move_abuf_float(float ** obuf,int nchans,int nsamps,int out_arate,float vol)888 int64_t sample_move_abuf_float(float **obuf, int nchans, int nsamps, int out_arate, float vol) {
889 int samples_out = 0;
890
891 #ifdef ENABLE_JACK
892
893 int samps = 0;
894
895 lives_audio_buf_t *abuf;
896 int in_arate;
897 off_t offs = 0, ioffs, xchan;
898
899 double src_offset_d = 0.f;
900 off_t src_offset_i = 0;
901
902 int i, j;
903
904 double scale;
905
906 size_t curval;
907
908 pthread_mutex_lock(&mainw->abuf_mutex);
909 if (mainw->jackd->read_abuf == -1) {
910 pthread_mutex_unlock(&mainw->abuf_mutex);
911 return 0;
912 }
913 abuf = mainw->jackd->abufs[mainw->jackd->read_abuf];
914 in_arate = abuf->arate;
915 pthread_mutex_unlock(&mainw->abuf_mutex);
916 scale = (double)in_arate / (double)out_arate;
917
918 while (nsamps > 0) {
919 pthread_mutex_lock(&mainw->abuf_mutex);
920 if (mainw->jackd->read_abuf == -1) {
921 pthread_mutex_unlock(&mainw->abuf_mutex);
922 return 0;
923 }
924
925 ioffs = abuf->start_sample;
926 pthread_mutex_unlock(&mainw->abuf_mutex);
927 samps = 0;
928
929 src_offset_i = 0;
930 src_offset_d = 0.;
931
932 for (i = 0; i < nsamps; i++) {
933 // process each sample
934
935 if ((curval = ioffs + src_offset_i) >= abuf->samples_filled) {
936 // current buffer is consumed
937 break;
938 }
939 xchan = 0;
940 for (j = 0; j < nchans; j++) {
941 // copy channel by channel (de-interleave)
942 pthread_mutex_lock(&mainw->abuf_mutex);
943 if (mainw->jackd->read_abuf < 0) {
944 pthread_mutex_unlock(&mainw->abuf_mutex);
945 return samples_out;
946 }
947 if (xchan >= abuf->out_achans) xchan = 0;
948 obuf[j][offs + i] = abuf->bufferf[xchan][curval] * vol;
949 pthread_mutex_unlock(&mainw->abuf_mutex);
950 xchan++;
951 }
952 // resample on the fly
953 src_offset_i = (off_t)((src_offset_d += scale) + .4999);
954 samps++;
955 samples_out++;
956 }
957
958 abuf->start_sample = ioffs + src_offset_i;
959 nsamps -= samps;
960 offs += samps;
961
962 if (nsamps > 0) {
963 // buffer was consumed, move on to next buffer
964 pthread_mutex_lock(&mainw->abuf_mutex);
965 // request caching thread to fill another buffer
966 mainw->abufs_to_fill++;
967 if (mainw->jackd->read_abuf < 0) {
968 // playback ended while we were processing
969 pthread_mutex_unlock(&mainw->abuf_mutex);
970 return samples_out;
971 }
972 mainw->jackd->read_abuf++;
973 wake_audio_thread();
974
975 if (mainw->jackd->read_abuf >= prefs->num_rtaudiobufs) mainw->jackd->read_abuf = 0;
976
977 abuf = mainw->jackd->abufs[mainw->jackd->read_abuf];
978
979 pthread_mutex_unlock(&mainw->abuf_mutex);
980 }
981 }
982 #endif
983
984 return samples_out;
985 }
986
987
988 /**
989 @brief copy audio data from cache into audio sound buffer
990 - int 16 version (e.g. pulseaudio)
991 nchans, nsamps. out_arate all refer to player values
992 */
sample_move_abuf_int16(short * obuf,int nchans,int nsamps,int out_arate)993 int64_t sample_move_abuf_int16(short *obuf, int nchans, int nsamps, int out_arate) {
994 int samples_out = 0;
995
996 #ifdef HAVE_PULSE_AUDIO
997
998 int samps = 0;
999
1000 lives_audio_buf_t *abuf;
1001 int in_arate, nsampsx;
1002 ssize_t offs = 0, ioffs, xchan;
1003
1004 double src_offset_d = 0.f;
1005 ssize_t src_offset_i = 0;
1006
1007 int i, j;
1008
1009 double scale;
1010 ssize_t curval;
1011
1012 pthread_mutex_lock(&mainw->abuf_mutex);
1013 if (mainw->pulsed->read_abuf == -1) {
1014 pthread_mutex_unlock(&mainw->abuf_mutex);
1015 return 0;
1016 }
1017
1018 abuf = mainw->pulsed->abufs[mainw->pulsed->read_abuf];
1019 in_arate = abuf->arate;
1020 pthread_mutex_unlock(&mainw->abuf_mutex);
1021 scale = (double)in_arate / (double)out_arate;
1022
1023 while (nsamps > 0) {
1024 pthread_mutex_lock(&mainw->abuf_mutex);
1025 if (mainw->pulsed->read_abuf == -1) {
1026 pthread_mutex_unlock(&mainw->abuf_mutex);
1027 return 0;
1028 }
1029
1030 ioffs = abuf->start_sample;
1031 pthread_mutex_unlock(&mainw->abuf_mutex);
1032 samps = 0;
1033
1034 src_offset_i = 0;
1035 src_offset_d = 0.;
1036 nsampsx = nsamps * nchans;
1037
1038 for (i = 0; i < nsampsx; i += nchans) {
1039 // process each sample
1040
1041 if ((curval = ioffs + src_offset_i) >= abuf->samples_filled) {
1042 // current buffer is drained
1043 break;
1044 }
1045 xchan = 0;
1046 curval *= abuf->out_achans;
1047 for (j = 0; j < nchans; j++) {
1048 pthread_mutex_lock(&mainw->abuf_mutex);
1049 if (mainw->pulsed->read_abuf < 0) {
1050 pthread_mutex_unlock(&mainw->abuf_mutex);
1051 return samps;
1052 }
1053 if (xchan >= abuf->out_achans) xchan = 0;
1054 obuf[(offs++)] = abuf->buffer16[0][curval + xchan];
1055 pthread_mutex_unlock(&mainw->abuf_mutex);
1056 xchan++;
1057 }
1058 src_offset_i = (ssize_t)((src_offset_d += scale) + .4999);
1059 samps++;
1060 }
1061
1062 abuf->start_sample = ioffs + src_offset_i;
1063 nsamps -= samps;
1064 samples_out += samps;
1065
1066 if (nsamps > 0) {
1067 // buffer was drained, move on to next buffer
1068 pthread_mutex_lock(&mainw->abuf_mutex);
1069 // request main thread to fill another buffer
1070 mainw->abufs_to_fill++;
1071
1072 if (mainw->pulsed->read_abuf < 0) {
1073 // playback ended while we were processing
1074 pthread_mutex_unlock(&mainw->abuf_mutex);
1075 return samples_out;
1076 }
1077
1078 mainw->pulsed->read_abuf++;
1079 wake_audio_thread();
1080 if (mainw->pulsed->read_abuf >= prefs->num_rtaudiobufs) mainw->pulsed->read_abuf = 0;
1081
1082 abuf = mainw->pulsed->abufs[mainw->pulsed->read_abuf];
1083 pthread_mutex_unlock(&mainw->abuf_mutex);
1084 }
1085 }
1086
1087 #endif
1088
1089 return samples_out;
1090 }
1091
1092
1093 /// copy a memory chunk into an audio buffer
1094
chunk_to_float_abuf(lives_audio_buf_t * abuf,float ** float_buffer,int nsamps)1095 static size_t chunk_to_float_abuf(lives_audio_buf_t *abuf, float **float_buffer, int nsamps) {
1096 int chans = abuf->out_achans;
1097 size_t offs = abuf->samples_filled;
1098 int i;
1099
1100 for (i = 0; i < chans; i++) {
1101 lives_memcpy(&(abuf->bufferf[i][offs]), float_buffer[i], nsamps * sizeof(float));
1102 }
1103 return (size_t)nsamps;
1104 }
1105
1106
float_deinterleave(float * fbuffer,int nsamps,int nchans)1107 boolean float_deinterleave(float *fbuffer, int nsamps, int nchans) {
1108 // deinterleave a float buffer
1109 int i, j;
1110
1111 float *tmpfbuffer = (float *)lives_calloc_safety(nsamps * nchans, sizeof(float));
1112 if (!tmpfbuffer) return FALSE;
1113
1114 for (i = 0; i < nsamps; i++) {
1115 for (j = 0; j < nchans; j++) {
1116 tmpfbuffer[nsamps * j + i] = fbuffer[i * nchans + j];
1117 }
1118 }
1119 lives_memcpy(fbuffer, tmpfbuffer, nsamps * nchans * sizeof(float));
1120 lives_free(tmpfbuffer);
1121 return TRUE;
1122 }
1123
1124
float_interleave(float * fbuffer,int nsamps,int nchans)1125 boolean float_interleave(float *fbuffer, int nsamps, int nchans) {
1126 // deinterleave a float buffer
1127 int i, j;
1128
1129 float *tmpfbuffer = (float *)lives_calloc_safety(nsamps * nchans, sizeof(float));
1130 if (!tmpfbuffer) return FALSE;
1131
1132 for (i = 0; i < nsamps; i++) {
1133 for (j = 0; j < nchans; j++) {
1134 tmpfbuffer[i * nchans + j] = fbuffer[j * nsamps + i];
1135 }
1136 }
1137 lives_memcpy(fbuffer, tmpfbuffer, nsamps * nchans * sizeof(float));
1138 lives_free(tmpfbuffer);
1139 return TRUE;
1140 }
1141
1142
1143 // for pulse audio we use S16LE interleaved, and the volume is adjusted later
1144
chunk_to_int16_abuf(lives_audio_buf_t * abuf,float ** float_buffer,int nsamps)1145 static size_t chunk_to_int16_abuf(lives_audio_buf_t *abuf, float **float_buffer, int nsamps) {
1146 int64_t frames_out;
1147 int chans = abuf->out_achans;
1148 size_t offs = abuf->samples_filled * chans;
1149
1150 frames_out = sample_move_float_int(abuf->buffer16[0] + offs, float_buffer, nsamps, 1., chans, 16,
1151 0, 0, 0, 1.0);
1152
1153 return (size_t)frames_out;
1154 }
1155
1156
1157 //#define DEBUG_ARENDER
1158
pad_with_silence(int out_fd,void * buff,off64_t oins_size,int64_t ins_size,int asamps,int aunsigned,boolean big_endian)1159 boolean pad_with_silence(int out_fd, void *buff, off64_t oins_size, int64_t ins_size, int asamps, int aunsigned,
1160 boolean big_endian) {
1161 // asamps is sample size in BYTES
1162 // fill to ins_pt with zeros (or 0x80.. for unsigned)
1163 // oins_size is the current file length, ins_size is the point where we want append to (both in bytes)
1164 // if ins size < oins_size we just seek to ins_size
1165 // otherwise we pad from oins_size to ins_size
1166
1167 static uint64_t *zero_buff = NULL;
1168 static int oasamps = 0;
1169 static int ounsigned = 0;
1170 static int orevendian = 0;
1171 size_t sbytes;
1172 size_t sblocksize = SILENCE_BLOCK_SIZE;
1173 int i;
1174
1175 boolean retval = TRUE;
1176 boolean revendian = FALSE;
1177
1178 //#define DEBUG_ARENDER
1179
1180 if (ins_size <= oins_size) {
1181 #ifdef DEBUG_ARENDER
1182 g_print("sbytes is l.t zero\n");
1183 #endif
1184 return FALSE;
1185 }
1186 sbytes = ins_size - oins_size;
1187
1188 #ifdef DEBUG_ARENDER
1189 g_print("sbytes is %ld\n", sbytes);
1190 #endif
1191 if (sbytes > 0) {
1192 if ((big_endian && capable->byte_order == LIVES_LITTLE_ENDIAN)
1193 || (!big_endian && capable->byte_order == LIVES_LITTLE_ENDIAN)) revendian = TRUE;
1194 if (out_fd >= 0) lives_lseek_buffered_writer(out_fd, oins_size);
1195 else {
1196 if (!buff) return FALSE;
1197 buff += oins_size;
1198 }
1199 if (zero_buff) {
1200 if (ounsigned != aunsigned || oasamps != asamps || orevendian != revendian) {
1201 lives_free(zero_buff);
1202 zero_buff = NULL;
1203 }
1204 }
1205 if (!zero_buff) {
1206 sblocksize >>= 3;
1207 zero_buff = (uint64_t *)lives_calloc_safety(sblocksize, 8);
1208 if (aunsigned) {
1209 if (asamps > 1) {
1210 uint64_t theval = (revendian ? 0x0080008000800080ul : 0x8000800080008000ul);
1211 for (i = 0; i < sblocksize; i ++) {
1212 zero_buff[i] = theval;
1213 }
1214 } else lives_memset(zero_buff, 0x80, SILENCE_BLOCK_SIZE);
1215 }
1216 sblocksize <<= 3;
1217 ounsigned = aunsigned;
1218 oasamps = asamps;
1219 orevendian = revendian;
1220 }
1221 for (i = 0; i < sbytes; i += SILENCE_BLOCK_SIZE) {
1222 if (sbytes - i < SILENCE_BLOCK_SIZE) sblocksize = sbytes - i;
1223 if (out_fd >= 0) {
1224 lives_write_buffered(out_fd, (const char *)zero_buff, sblocksize, TRUE);
1225 if (THREADVAR(write_failed) == out_fd + 1) {
1226 THREADVAR(write_failed) = 0;
1227 retval = FALSE;
1228 }
1229 } else {
1230 lives_memcpy(buff, zero_buff, sblocksize);
1231 buff += sblocksize;
1232 }
1233 }
1234 } else if (out_fd >= 0) {
1235 lives_lseek_buffered_writer(out_fd, ins_size);
1236 }
1237 return retval;
1238 }
1239
1240
audio_process_events_to(weed_timecode_t tc)1241 LIVES_LOCAL_INLINE void audio_process_events_to(weed_timecode_t tc) {
1242 if (tc >= get_event_timecode(mainw->audio_event)) {
1243 #ifdef DEBUG_ARENDER
1244 g_print("smallblock %ld to %ld\n", weed_event_get_timecode(mainw->audio_event), tc);
1245 #endif
1246 get_audio_and_effects_state_at(NULL, mainw->audio_event, tc, LIVES_PREVIEW_TYPE_AUDIO_ONLY, FALSE);
1247 }
1248 }
1249
1250
1251 /**
1252 @brief render a chunk of audio, apply effects and mixing it
1253
1254 called during multitrack rendering to create the actual audio file
1255 (or in-memory buffer for preview playback in multitrack)
1256
1257 also used for fade-in/fade-out in the clip editor (opvol_start, opvol_end)
1258
1259 in multitrack, chvol is taken from the audio mixer; opvol is always 1.
1260
1261 what we will do here:
1262 calculate our target samples (= period * out_rate)
1263
1264 calculate how many in_samples for each track (= period * in_rate / ABS (vel) )
1265
1266 read in the relevant number of samples for each track and convert to float
1267
1268 write this into our float buffers (1 buffer per channel per track)
1269
1270 we then send small chunks at a time to any audio effects; this is to allow for parameter interpolation
1271
1272 the small chunks are processed and mixed, converted from float back to int, and then written to the outfile
1273
1274 if obuf != NULL we write to obuf instead */
1275 //#define DEBUG_ARENDER
render_audio_segment(int nfiles,int * from_files,int to_file,double * avels,double * fromtime,weed_timecode_t tc_start,weed_timecode_t tc_end,double * chvol,double opvol_start,double opvol_end,lives_audio_buf_t * obuf)1276 int64_t render_audio_segment(int nfiles, int *from_files, int to_file, double *avels, double *fromtime,
1277 weed_timecode_t tc_start, weed_timecode_t tc_end, double *chvol, double opvol_start,
1278 double opvol_end, lives_audio_buf_t *obuf) {
1279
1280 // TODO - allow MAX_AUDIO_MEM to be configurable; currently this is fixed at 8 MB
1281 // 16 or 32 may be a more sensible default for realtime previewing
1282 // return (audio) frames rendered
1283
1284 weed_plant_t *shortcut = NULL;
1285 lives_clip_t *outfile = to_file > -1 ? mainw->files[to_file] : NULL;
1286 uint8_t *in_buff;
1287 void *finish_buff = NULL; ///< only used if we are writing output to a file
1288 double *vis = NULL;
1289 short *holding_buff;
1290 weed_layer_t **layers = NULL;
1291 char *infilename, *outfilename;
1292 off64_t seekstart[nfiles];
1293 off_t seek;
1294
1295 int in_fd[nfiles];
1296 int in_asamps[nfiles];
1297 int in_achans[nfiles];
1298 int in_arate[nfiles];
1299 int in_arps[nfiles];
1300 int in_unsigned[nfiles];
1301
1302 boolean in_reverse_endian[nfiles];
1303 boolean is_silent[nfiles];
1304
1305 size_t max_aud_mem, bytes_to_read, aud_buffer;
1306 size_t tbytes;
1307
1308 ssize_t bytes_read;
1309
1310 uint64_t nframes;
1311
1312 weed_timecode_t tc = tc_start;
1313
1314 double ins_pt = tc / TICKS_PER_SECOND_DBL;
1315 double time = 0.;
1316 double opvol = opvol_start;
1317 double zavel, zzavel, zavel_max = 0.;
1318
1319 boolean out_reverse_endian = FALSE;
1320 boolean is_fade = FALSE;
1321 boolean use_live_chvols = FALSE;
1322
1323 int out_asamps = to_file > -1 ? outfile->asampsize / 8 : obuf->out_asamps / 8;
1324 int out_achans = to_file > -1 ? outfile->achans : obuf->out_achans;
1325 int out_arate = to_file > -1 ? outfile->arate : obuf->arate;
1326 int out_unsigned = to_file > -1 ? outfile->signed_endian & AFORM_UNSIGNED : 0;
1327 int out_bendian = to_file > -1 ? outfile->signed_endian & AFORM_BIG_ENDIAN : 0;
1328
1329 int track;
1330 int in_bendian;
1331 int first_nonsilent = -1;
1332 int max_segments;
1333 int render_block_size = RENDER_BLOCK_SIZE;
1334 int c, x, y;
1335 int out_fd = -1;
1336
1337 int i;
1338
1339 int64_t frames_out = 0;
1340 int64_t ins_size = 0l, cur_size;
1341 int64_t tsamples = ((double)(tc_end - tc_start) / TICKS_PER_SECOND_DBL * (double)out_arate + .5);
1342 int64_t blocksize, zsamples, xsamples;
1343 int64_t tot_frames = 0l;
1344
1345 float *float_buffer[out_achans * nfiles];
1346 float *chunk_float_buffer[out_achans * nfiles];
1347 float clip_vol;
1348
1349 if (out_achans * nfiles * tsamples == 0) return 0l;
1350
1351 if (to_file > -1 && !mainw->multitrack && opvol_start != opvol_end) is_fade = TRUE;
1352
1353 if (!storedfdsset) audio_reset_stored_fnames();
1354
1355 if (!is_fade && (!mainw->event_list || (!mainw->multitrack && nfiles == 1 && from_files &&
1356 from_files && from_files[0] == mainw->ascrap_file)))
1357 render_block_size *= 100;
1358
1359 if (to_file > -1) {
1360 // prepare outfile stuff
1361 outfilename = lives_get_audio_file_name(to_file);
1362 #ifdef DEBUG_ARENDER
1363 g_print("writing to %s\n", outfilename);
1364 #endif
1365 out_fd = lives_open_buffered_writer(outfilename, S_IRUSR | S_IWUSR, FALSE);
1366 lives_free(outfilename);
1367
1368 if (out_fd < 0) {
1369 lives_freep((void **)&THREADVAR(write_failed_file));
1370 THREADVAR(write_failed_file) = lives_strdup(outfilename);
1371 THREADVAR(write_failed) = -2;
1372 return 0l;
1373 }
1374
1375 cur_size = lives_buffered_orig_size(out_fd);
1376
1377 if (opvol_start == opvol_end && opvol_start == 0.) ins_pt = tc_end / TICKS_PER_SECOND_DBL;
1378 ins_pt *= out_achans * out_arate * out_asamps;
1379 ins_size = ((int64_t)(ins_pt / out_achans / out_asamps + .5)) * out_achans * out_asamps;
1380
1381 if ((!out_bendian && (capable->byte_order == LIVES_BIG_ENDIAN)) ||
1382 (out_bendian && (capable->byte_order == LIVES_LITTLE_ENDIAN)))
1383 out_reverse_endian = TRUE;
1384 else out_reverse_endian = FALSE;
1385
1386 if (ins_size > cur_size) {
1387 // fill to ins_pt with zeros
1388 pad_with_silence(out_fd, NULL, cur_size, ins_size, out_asamps, out_unsigned, out_bendian);
1389 } else lives_lseek_buffered_writer(out_fd, ins_size);
1390
1391 if (opvol_start == opvol_end && opvol_start == 0.) {
1392 lives_close_buffered(out_fd);
1393 return tsamples;
1394 }
1395 } else {
1396 if (mainw->event_list) cfile->aseek_pos = fromtime[0];
1397
1398 tc_end -= tc_start;
1399 tc_start = 0;
1400
1401 if (tsamples > obuf->samp_space - obuf->samples_filled) tsamples = obuf->samp_space - obuf->samples_filled;
1402 }
1403
1404 #ifdef DEBUG_ARENDER
1405 g_print("here %d %ld %ld %d\n", nfiles, tc_start, tc_end, to_file);
1406 #endif
1407
1408 for (track = 0; track < nfiles; track++) {
1409 // prepare infile stuff
1410 lives_clip_t *infile;
1411
1412 #ifdef DEBUG_ARENDER
1413 g_print(" track %d %d %.4f %.4f\n", track, from_files[track], fromtime[track], avels[track]);
1414 #endif
1415
1416 if (avels[track] == 0.) {
1417 is_silent[track] = TRUE;
1418 continue;
1419 }
1420
1421 is_silent[track] = FALSE;
1422 infile = mainw->files[from_files[track]];
1423
1424 in_asamps[track] = infile->asampsize / 8;
1425 in_achans[track] = infile->achans;
1426 in_arate[track] = infile->arate;
1427 in_arps[track] = infile->arps;
1428 in_unsigned[track] = infile->signed_endian & AFORM_UNSIGNED;
1429 in_bendian = infile->signed_endian & AFORM_BIG_ENDIAN;
1430
1431 if (LIVES_UNLIKELY(in_achans[track] == 0)) is_silent[track] = TRUE;
1432 else {
1433 if ((!in_bendian && (capable->byte_order == LIVES_BIG_ENDIAN)) ||
1434 (in_bendian && (capable->byte_order == LIVES_LITTLE_ENDIAN)))
1435 in_reverse_endian[track] = TRUE;
1436 else in_reverse_endian[track] = FALSE;
1437
1438 /// this is not the velocity we will use for reading, but we need to estimate how many bytes we will read in
1439 /// so we can calculate how many buffers to allocate
1440 zavel = avels[track] * (double)in_arate[track] / (double)out_arate * in_asamps[track] * in_achans[track];
1441
1442 if (fabs(zavel) > zavel_max) zavel_max = fabs(zavel);
1443
1444 infilename = lives_get_audio_file_name(from_files[track]);
1445
1446 // try to speed up access by keeping some files open
1447 if (track < NSTOREDFDS && storedfnames[track] && !strcmp(infilename, storedfnames[track])) {
1448 in_fd[track] = storedfds[track];
1449 } else {
1450 if (track < NSTOREDFDS && storedfds[track] > -1) lives_close_buffered(storedfds[track]);
1451 in_fd[track] = lives_open_buffered_rdonly(infilename);
1452 if (in_fd[track] < 0) {
1453 lives_freep((void **)&THREADVAR(read_failed_file));
1454 THREADVAR(read_failed_file) = lives_strdup(infilename);
1455 THREADVAR(read_failed) = -2;
1456 } else {
1457 if (track < NSTOREDFDS) {
1458 storedfds[track] = in_fd[track];
1459 storedfnames[track] = lives_strdup(infilename);
1460 }
1461 }
1462 }
1463 seek = lives_buffered_offset(in_fd[track]);
1464 seekstart[track] = quant_abytes(fromtime[track], in_arps[track], in_achans[track], in_asamps[track]);
1465 if (labs(seekstart[track] - seek) > AUD_DIFF_MIN) {
1466 lives_lseek_buffered_rdonly_absolute(in_fd[track], seekstart[track]);
1467 }
1468 lives_free(infilename);
1469 }
1470 }
1471
1472 for (track = 0; track < nfiles; track++) {
1473 if (!is_silent[track]) {
1474 first_nonsilent = track;
1475 break;
1476 }
1477 }
1478
1479 if (first_nonsilent == -1) {
1480 // all in tracks are empty
1481 // output silence
1482 if (to_file > -1) {
1483 int64_t oins_size = ins_size;
1484 ins_pt = tc_end / TICKS_PER_SECOND_DBL;
1485 ins_pt *= out_achans * out_arate * out_asamps;
1486 ins_size = ((int64_t)(ins_pt / out_achans / out_asamps) + .5) * out_achans * out_asamps;
1487 pad_with_silence(out_fd, NULL, oins_size, ins_size, out_asamps, out_unsigned, out_bendian);
1488 lives_close_buffered(out_fd);
1489 } else {
1490 if (prefs->audio_player == AUD_PLAYER_JACK) {
1491 for (i = 0; i < out_achans; i++) {
1492 lives_memset((void *)obuf->bufferf[i] + obuf->samples_filled * sizeof(float), 0, tsamples * sizeof(float));
1493 }
1494 } else {
1495 pad_with_silence(-1, (void *)obuf->buffer16[0], obuf->samples_filled * out_asamps * out_achans,
1496 (obuf->samples_filled + tsamples) * out_asamps * out_achans, out_asamps, obuf->s16_signed
1497 ? AFORM_SIGNED : AFORM_UNSIGNED,
1498 ((capable->byte_order == LIVES_LITTLE_ENDIAN && obuf->swap_endian == SWAP_L_TO_X)
1499 || (capable->byte_order == LIVES_LITTLE_ENDIAN && obuf->swap_endian != SWAP_L_TO_X)));
1500 }
1501 obuf->samples_filled += tsamples;
1502 }
1503 return tsamples;
1504 }
1505
1506 /// we don't want to use more than MAX_AUDIO_MEM bytes
1507 /// (numbers will be much larger than examples given)
1508 max_aud_mem = MAX_AUDIO_MEM / (1.5 + zavel_max); // allow for size of holding_buff and in_buff
1509 max_aud_mem = (max_aud_mem >> 7) << 7; // round to a multiple of 128
1510 max_aud_mem = max_aud_mem / out_achans / nfiles; // max mem per channel/track
1511
1512 // we use float here because our audio effects use float
1513 // tsamples is total samples (30 in this example)
1514 bytes_to_read = tsamples * (sizeof(float)); // eg. 120 (30 samples)
1515
1516 // how many segments do we need to read all bytes ?
1517 max_segments = (int)((double)bytes_to_read / (double)max_aud_mem + 1.); // max segments (rounded up) [e.g ceil(120/45)==3]
1518
1519 // then, how many bytes per segment
1520 aud_buffer = bytes_to_read / max_segments; // estimate of buffer size (e.g. 120/3 = 40)
1521
1522 zsamples = (int)(aud_buffer / sizeof(float) + .5); // ensure whole number of samples (e.g 40 == 10 samples), round up
1523
1524 xsamples = zsamples + (tsamples - (max_segments * zsamples)); // e.g 10 + 30 - 3 * 10 == 10
1525
1526 holding_buff = (short *)lives_calloc_safety(xsamples * out_achans, sizeof(short));
1527
1528 for (i = 0; i < out_achans * nfiles; i++) {
1529 float_buffer[i] = (float *)lives_calloc_safety(xsamples, sizeof(float));
1530 }
1531
1532 if (to_file > -1)
1533 finish_buff = lives_calloc_safety(tsamples, out_achans * out_asamps);
1534
1535 #ifdef DEBUG_ARENDER
1536 g_print(" rendering %ld samples %f\n", tsamples, opvol);
1537 #endif
1538
1539 // TODO - need to check amixer and get vals from sliders
1540 /* if (mainw->multitrack && mainw->multitrack->audio_vols && obuf) { */
1541 /* use_live_chvols = TRUE; */
1542 /* audio_vols = mainw->multitrack->audio_vols; */
1543 /* } */
1544
1545 while (tsamples > 0) {
1546 tsamples -= xsamples;
1547
1548 for (track = 0; track < nfiles; track++) {
1549 if (is_silent[track]) {
1550 // zero float_buff
1551 for (c = 0; c < out_achans; c++) {
1552 lives_memset(float_buffer[track * out_achans + c], 0, xsamples * sizeof(float));
1553 }
1554 continue;
1555 }
1556 /// calculate tbytes for xsamples
1557 zavel = avels[track] * (double)in_arate[track] / (double)out_arate;
1558
1559 //g_print("zavel is %f\n", zavel);
1560 /// tbytes: how many bytes we want to read in. This is xsamples * the track velocity.
1561 /// we add a small random factor here, so half the time we round up, half the time we round down
1562 /// otherwise we would be gradually losing or gaining samples
1563 tbytes = (int)((double)xsamples * fabs(zavel) + ((double)fastrand() / (double)LIVES_MAXUINT64)) *
1564 in_asamps[track] * in_achans[track];
1565
1566 if (tbytes <= 0) {
1567 for (c = 0; c < out_achans; c++) {
1568 lives_memset(float_buffer[track * out_achans + c], 0, xsamples * sizeof(float));
1569 }
1570 continue;
1571 }
1572
1573 in_buff = (uint8_t *)lives_calloc_safety(tbytes, 1);
1574
1575 if (in_fd[track] > -1) {
1576 if (zavel < 0.) {
1577 lives_buffered_rdonly_set_reversed(in_fd[track], TRUE);
1578 lives_lseek_buffered_rdonly(in_fd[track], - tbytes);
1579 } else {
1580 lives_buffered_rdonly_set_reversed(in_fd[track], FALSE);
1581 //lives_buffered_rdonly_slurp(in_fd[track], seekstart[track]);
1582 }
1583 }
1584
1585 bytes_read = 0;
1586
1587 if (in_fd[track] > -1) bytes_read = lives_read_buffered(in_fd[track], in_buff, tbytes, TRUE);
1588
1589 if (bytes_read < 0) bytes_read = 0;
1590
1591 if (in_fd[track] > -1) {
1592 if (zavel < 0.) {
1593 lives_lseek_buffered_rdonly(in_fd[track], -tbytes);
1594 }
1595 }
1596
1597 fromtime[track] = (double)lives_buffered_offset(in_fd[track])
1598 / (double)(in_asamps[track] * in_achans[track] * in_arate[track]);
1599
1600 if (from_files[track] == mainw->ascrap_file) {
1601 // be forgiving with the ascrap file
1602 if (THREADVAR(read_failed) == in_fd[track] + 1) {
1603 THREADVAR(read_failed) = 0;
1604 }
1605 }
1606
1607 if (bytes_read < tbytes && bytes_read >= 0) {
1608 pad_with_silence(-1, in_buff, bytes_read, tbytes, in_asamps[track], mainw->files[from_files[track]]->signed_endian
1609 & AFORM_UNSIGNED, mainw->files[from_files[track]]->signed_endian & AFORM_BIG_ENDIAN);
1610 //lives_memset(in_buff + bytes_read, 0, tbytes - bytes_read);
1611 }
1612
1613 nframes = (tbytes / (in_asamps[track]) / in_achans[track] / fabs(zavel) + .001);
1614
1615 /// convert to float
1616 /// - first we convert to 16 bit stereo (if it was 8 bit and / or mono) and we resample
1617 /// input is tbytes bytes at rate * velocity, and we should get out nframes audio frames at out_arate. out_achans
1618 /// result is in holding_buff
1619 zzavel = zavel;
1620 if (in_asamps[track] == 1) {
1621 if (zavel < 0.) {
1622 if (reverse_buffer(in_buff, tbytes, in_achans[track]))
1623 zavel = -zavel;
1624 }
1625 sample_move_d8_d16(holding_buff, (uint8_t *)in_buff, nframes, tbytes, zavel, out_achans, in_achans[track], 0);
1626 } else {
1627 if (zavel < 0.) {
1628 if (reverse_buffer(in_buff, tbytes, in_achans[track] * 2))
1629 zavel = -zavel;
1630 }
1631 sample_move_d16_d16(holding_buff, (short *)in_buff, nframes, tbytes, zavel, out_achans,
1632 in_achans[track], in_reverse_endian[track] ? SWAP_X_TO_L : 0, 0);
1633 }
1634 zavel = zzavel;
1635 lives_free(in_buff);
1636 /// if we are previewing a rendering, we would get double the volume adjustment, once from the rendering and again from
1637 /// the audio player, so in that case we skip the adjustment here
1638 if (!mainw->preview_rendering) clip_vol = lives_vol_from_linear(mainw->files[from_files[track]]->vol);
1639 else clip_vol = 1.;
1640 for (c = 0; c < out_achans; c++) {
1641 /// now we convert to holding_buff to float in float_buffer and adjust the track volume
1642 sample_move_d16_float(float_buffer[c + track * out_achans], holding_buff + c, nframes,
1643 out_achans, in_unsigned[track], FALSE, clip_vol * (use_live_chvols ? 1. : chvol[track]));
1644 }
1645 }
1646
1647 // next we send small chunks at a time to the audio vol/pan effect + any other audio effects
1648 shortcut = NULL;
1649 blocksize = render_block_size; ///< this is our chunk size
1650
1651 for (i = 0; i < xsamples; i += render_block_size) {
1652 if (i + render_block_size > xsamples) blocksize = xsamples - i;
1653
1654 for (track = 0; track < nfiles; track++) {
1655 /* if (use_live_chvols) { */
1656 /* chvol[track] = giw_vslider_get_value(GIW_VSLIDER(amixer->ch_sliders[track])); */
1657 /* } */
1658 for (c = 0; c < out_achans; c++) {
1659 //g_print("xvals %.4f\n",*(float_buffer[track*out_achans+c]+i));
1660 chunk_float_buffer[track * out_achans + c] = float_buffer[track * out_achans + c] + i;
1661 /* if (use_live_chvols) { */
1662 /* for (smp = 0; smp < blocksize; smp++) chunk_float_buffer[track * out_achans + c][smp] *= chvol[track]; */
1663 /* } */
1664 }
1665 }
1666
1667 if (mainw->event_list && !(!mainw->multitrack && from_files[0] == mainw->ascrap_file)) {
1668 // we need to apply all audio effects with output here.
1669 // even in clipedit mode (for preview/rendering with an event list)
1670 // also, we will need to keep updating mainw->afilter_map from mainw->event_list,
1671 // as filters may switched on and off during the block
1672
1673 int nbtracks = 0;
1674
1675 // process events up to current tc:
1676 // filter inits and deinits, and filter maps will update the current fx state
1677 if (tc > 0) audio_process_events_to(tc);
1678
1679 if (mainw->multitrack || mainw->afilter_map) {
1680
1681 // apply audio filter(s)
1682 if (mainw->multitrack) {
1683 /// here we work out the "visibility" of each track at tc (i.e we only get audio from the front track + backing audio)
1684 /// any transitions will combine audio from 2 layers (if the pref is set)
1685 /// backing audio tracks are always full visible
1686 /// the array is used to set the values of the "is_volume_master" parameter of the effect (see the Weed Audio spec.)
1687 vis = get_track_visibility_at_tc(mainw->multitrack->event_list, nfiles,
1688 mainw->multitrack->opts.back_audio_tracks, tc, &shortcut,
1689 mainw->multitrack->opts.audio_bleedthru);
1690
1691 /// first track is ascrap_file - flag that no effects should be applied to it, except for the audio mixer
1692 /// since effects were already applied to the saved audio
1693 if (mainw->ascrap_file > -1 && from_files[0] == mainw->ascrap_file) vis[0] = -vis[0];
1694
1695 nbtracks = mainw->multitrack->opts.back_audio_tracks;
1696 }
1697
1698 /// the audio is now packaged into audio layers, one for each track (file). This makes it easier to remap
1699 /// the audio tracks from effect to effect, as layers are interchangeable with filter channels
1700 layers = (weed_layer_t **)lives_calloc(nfiles, sizeof(weed_layer_t *));
1701 for (x = 0; x < nfiles; x++) {
1702 float **adata = (float **)lives_calloc(out_achans, sizeof(float *));
1703 layers[x] = weed_layer_new(WEED_LAYER_TYPE_AUDIO);
1704 for (y = 0; y < out_achans; y++) {
1705 adata[y] = chunk_float_buffer[x * out_achans + y];
1706 }
1707
1708 weed_layer_set_audio_data(layers[x], adata, out_arate, out_achans, blocksize);
1709 lives_free(adata);
1710 weed_set_boolean_value(layers[x], WEED_LEAF_HOST_KEEP_ADATA, WEED_TRUE);
1711 }
1712
1713 /// apply the audo effects
1714 weed_apply_audio_effects(mainw->afilter_map, layers, nbtracks, out_achans, blocksize, out_arate, tc, vis);
1715 lives_freep((void **)&vis);
1716
1717 if (layers) {
1718 /// after processing we get the audio data back from the layers
1719 for (x = 0; x < nfiles; x++) {
1720 float **adata = (weed_layer_get_audio_data(layers[x], NULL));
1721 for (y = 0; y < out_achans; y++) {
1722 if (chunk_float_buffer[x * out_achans + y] != adata[y]) {
1723 /// non-inplace, audio was replaced so wee need to copy to float_buffer and free
1724 lives_memcpy(chunk_float_buffer[x * out_achans + y], adata[y], weed_layer_get_audio_length(layers[x])
1725 * sizeof(float));
1726 lives_free(adata[y]);
1727 }
1728 }
1729 lives_free(adata);
1730 weed_layer_set_audio_data(layers[x], NULL, 0, 0, 0);
1731 weed_layer_free(layers[x]);
1732 }
1733 lives_freep((void **)&layers);
1734 }
1735 }
1736 }
1737
1738 if (!mainw->multitrack && opvol_end != opvol_start) {
1739 time += (double)frames_out / (double)out_arate;
1740 opvol = opvol_start + (opvol_end - opvol_start) * (time / (double)((tc_end - tc_start) / TICKS_PER_SECOND_DBL));
1741 opvol = lives_vol_from_linear(opvol);
1742 }
1743
1744 if (is_fade) {
1745 // output to file
1746 // convert back to int; use out_scale of 1., since we did our resampling in sample_move_*_d16
1747 frames_out = sample_move_float_int((void *)finish_buff, chunk_float_buffer, blocksize, 1., out_achans,
1748 out_asamps * 8, out_unsigned, out_reverse_endian, FALSE, opvol);
1749 lives_write_buffered(out_fd, finish_buff, frames_out * out_asamps * out_achans, TRUE);
1750 threaded_dialog_spin(0.);
1751 tot_frames += frames_out;
1752 #ifdef DEBUG_ARENDER
1753 g_print(".");
1754 #endif
1755 }
1756
1757 tc += (double)blocksize / (double)out_arate * TICKS_PER_SECOND_DBL;
1758 }
1759
1760 if (!is_fade) {
1761 if (to_file > -1) {
1762 /// output to file:
1763 /// convert back to int; use out_scale of 1., since we did our resampling in sample_move_*_d16
1764 frames_out = sample_move_float_int((void *)finish_buff, float_buffer, xsamples, 1., out_achans,
1765 out_asamps * 8, out_unsigned, out_reverse_endian, FALSE, opvol);
1766
1767 lives_write_buffered(out_fd, finish_buff, frames_out * out_asamps * out_achans, TRUE);
1768 #ifdef DEBUG_ARENDER
1769 g_print(".");
1770 #endif
1771 tot_frames += frames_out;
1772 } else {
1773 /// output to memory buffer; for jack we retain the float audio, for pulse we use int16_t
1774 if (prefs->audio_player == AUD_PLAYER_JACK) {
1775 frames_out = chunk_to_float_abuf(obuf, float_buffer, xsamples);
1776 } else {
1777 frames_out = chunk_to_int16_abuf(obuf, float_buffer, xsamples);
1778 }
1779 obuf->samples_filled += frames_out;
1780 tot_frames += frames_out;
1781 }
1782 }
1783 xsamples = zsamples;
1784 }
1785
1786 if (xsamples > 0) {
1787 for (i = 0; i < out_achans * nfiles; i++) {
1788 if (float_buffer[i]) lives_free(float_buffer[i]);
1789 }
1790 }
1791
1792 if (finish_buff) lives_free(finish_buff);
1793 if (holding_buff) lives_free(holding_buff);
1794
1795 // close files
1796 for (track = 0; track < nfiles; track++) {
1797 if (!is_silent[track]) {
1798 if (track >= NSTOREDFDS && in_fd[track] > -1) lives_close_buffered(in_fd[track]);
1799 }
1800 }
1801 //#define DEBUG_ARENDER
1802 if (to_file > -1) {
1803 #ifdef DEBUG_ARENDER
1804 g_print("fs is %ld %s\n", get_file_size(out_fd), cfile->handle);
1805 #endif
1806 lives_close_buffered(out_fd);
1807 }
1808
1809 return tot_frames;
1810 }
1811
1812
aud_fade(int fileno,double startt,double endt,double startv,double endv)1813 void aud_fade(int fileno, double startt, double endt, double startv, double endv) {
1814 double vel = 1., vol = 1.;
1815
1816 render_audio_segment(1, &fileno, fileno, &vel, &startt, (weed_timecode_t)(startt * TICKS_PER_SECOND_DBL),
1817 (weed_timecode_t)(endt * TICKS_PER_SECOND_DBL), &vol, startv, endv, NULL);
1818
1819 if (THREADVAR(write_failed)) {
1820 char *outfilename = lives_get_audio_file_name(fileno);
1821 THREADVAR(write_failed) = 0;
1822 do_write_failed_error_s(outfilename, NULL);
1823 lives_free(outfilename);
1824 }
1825
1826 if (THREADVAR(read_failed)) {
1827 char *infilename = lives_get_audio_file_name(fileno);
1828 THREADVAR(read_failed) = 0;
1829 do_read_failed_error_s(infilename, NULL);
1830 lives_free(infilename);
1831 }
1832 }
1833
1834
preview_audio(void)1835 void preview_audio(void) {
1836 // start a minimalistic player with only audio
1837 mainw->play_start = cfile->start;
1838 mainw->play_end = cfile->end;
1839 mainw->playing_sel = TRUE;
1840
1841 if (cfile->achans > 0) {
1842 cfile->aseek_pos = (off64_t)(cfile->real_pointer_time * cfile->arate) * cfile->achans * (cfile->asampsize / 8);
1843 if (mainw->playing_sel) {
1844 off64_t apos = (off64_t)((double)(mainw->play_start - 1.) / cfile->fps * cfile->arate) * cfile->achans *
1845 (cfile->asampsize / 8);
1846 if (apos > cfile->aseek_pos) cfile->aseek_pos = apos;
1847 }
1848 if (cfile->aseek_pos > cfile->afilesize) cfile->aseek_pos = 0.;
1849 if (mainw->current_file == 0 && cfile->arate < 0) cfile->aseek_pos = cfile->afilesize;
1850 }
1851 // start up our audio player (jack or pulse)
1852 #ifdef ENABLE_JACK
1853 if (prefs->audio_player == AUD_PLAYER_JACK) {
1854 if (mainw->jackd) jack_aud_pb_ready(mainw->current_file);
1855 }
1856 #endif
1857 #ifdef HAVE_PULSE_AUDIO
1858 if (prefs->audio_player == AUD_PLAYER_PULSE) {
1859 if (mainw->pulsed) pulse_aud_pb_ready(mainw->current_file);
1860 }
1861 #endif
1862 #ifdef ENABLE_JACK
1863 if (prefs->audio_player == AUD_PLAYER_JACK) {
1864 mainw->write_abuf = 0;
1865
1866 // fill our audio buffers now
1867 // this will also get our effects state
1868 pthread_mutex_lock(&mainw->abuf_mutex);
1869 mainw->jackd->read_abuf = 0;
1870 mainw->abufs_to_fill = 0;
1871 pthread_mutex_unlock(&mainw->abuf_mutex);
1872 if (mainw->event_list)
1873 mainw->jackd->is_paused = mainw->jackd->in_use = TRUE;
1874 }
1875 #endif
1876 mainw->playing_file = mainw->current_file;
1877 #ifdef ENABLE_JACK
1878 if (prefs->audio_player == AUD_PLAYER_JACK && cfile->achans > 0 && cfile->laudio_time > 0. &&
1879 !mainw->is_rendering && !(cfile->opening && !mainw->preview) && mainw->jackd
1880 && mainw->jackd->playing_file > -1) {
1881 if (!jack_audio_seek_frame(mainw->jackd, mainw->aframeno)) {
1882 if (jack_try_reconnect()) jack_audio_seek_frame(mainw->jackd, mainw->aframeno);
1883 else mainw->video_seek_ready = mainw->audio_seek_ready = TRUE;
1884 }
1885 }
1886 #endif
1887 #ifdef HAVE_PULSE_AUDIO
1888 if (prefs->audio_player == AUD_PLAYER_PULSE && cfile->achans > 0 && cfile->laudio_time > 0. &&
1889 !mainw->is_rendering && !(cfile->opening && !mainw->preview) && mainw->pulsed
1890 && mainw->pulsed->playing_file > -1) {
1891 if (!pulse_audio_seek_frame(mainw->pulsed, mainw->aframeno)) {
1892 handle_audio_timeout();
1893 return;
1894 }
1895 }
1896 #endif
1897
1898 while (mainw->cancelled == CANCEL_NONE) {
1899 mainw->video_seek_ready = TRUE;
1900 lives_nanosleep(1000);
1901 }
1902 mainw->playing_file = -1;
1903
1904 // reset audio buffers
1905 #ifdef ENABLE_JACK
1906 if (prefs->audio_player == AUD_PLAYER_JACK && mainw->jackd) {
1907 // must do this before deinit fx
1908 pthread_mutex_lock(&mainw->abuf_mutex);
1909 mainw->jackd->read_abuf = -1;
1910 mainw->jackd->in_use = FALSE;
1911 pthread_mutex_unlock(&mainw->abuf_mutex);
1912 }
1913 #endif
1914
1915 #ifdef HAVE_PULSE_AUDIO
1916 if (prefs->audio_player == AUD_PLAYER_PULSE && mainw->pulsed) {
1917 pthread_mutex_lock(&mainw->abuf_mutex);
1918 mainw->pulsed->read_abuf = -1;
1919 mainw->pulsed->in_use = FALSE;
1920 pthread_mutex_unlock(&mainw->abuf_mutex);
1921 }
1922 #endif
1923
1924 mainw->playing_sel = FALSE;
1925 lives_ce_update_timeline(0, cfile->real_pointer_time);
1926 if (mainw->cancelled == CANCEL_AUDIO_ERROR) {
1927 handle_audio_timeout();
1928 }
1929
1930 #ifdef ENABLE_JACK
1931 if (prefs->audio_player == AUD_PLAYER_JACK && (mainw->jackd || mainw->jackd_read)) {
1932 // tell jack client to close audio file
1933 if (mainw->jackd && mainw->jackd->playing_file > 0) {
1934 ticks_t timeout = 0;
1935 if (mainw->cancelled != CANCEL_AUDIO_ERROR) {
1936 lives_alarm_t alarm_handle = lives_alarm_set(LIVES_DEFAULT_TIMEOUT);
1937 while ((timeout = lives_alarm_check(alarm_handle)) > 0 && jack_get_msgq(mainw->jackd) != NULL) {
1938 sched_yield(); // wait for seek
1939 lives_usleep(prefs->sleep_time);
1940 }
1941 lives_alarm_clear(alarm_handle);
1942 }
1943 if (mainw->cancelled == CANCEL_AUDIO_ERROR) mainw->cancelled = CANCEL_ERROR;
1944 jack_message.command = ASERVER_CMD_FILE_CLOSE;
1945 jack_message.data = NULL;
1946 jack_message.next = NULL;
1947 mainw->jackd->msgq = &jack_message;
1948 if (timeout == 0) handle_audio_timeout();
1949 }
1950 }
1951 #endif
1952 #ifdef HAVE_PULSE_AUDIO
1953 if (prefs->audio_player == AUD_PLAYER_PULSE && (mainw->pulsed || mainw->pulsed_read)) {
1954 // tell pulse client to close audio file
1955 if (mainw->pulsed) {
1956 if (mainw->pulsed->playing_file > 0 || mainw->pulsed->fd > 0) {
1957 ticks_t timeout = 0;
1958 if (mainw->cancelled != CANCEL_AUDIO_ERROR) {
1959 lives_alarm_t alarm_handle = lives_alarm_set(LIVES_DEFAULT_TIMEOUT);
1960 while ((timeout = lives_alarm_check(alarm_handle)) > 0 && pulse_get_msgq(mainw->pulsed) != NULL) {
1961 sched_yield(); // wait for seek
1962 lives_usleep(prefs->sleep_time);
1963 }
1964 lives_alarm_clear(alarm_handle);
1965 }
1966 if (mainw->cancelled == CANCEL_AUDIO_ERROR) mainw->cancelled = CANCEL_ERROR;
1967 pulse_message.command = ASERVER_CMD_FILE_CLOSE;
1968 pulse_message.data = NULL;
1969 pulse_message.next = NULL;
1970 mainw->pulsed->msgq = &pulse_message;
1971 if (timeout == 0) {
1972 handle_audio_timeout();
1973 mainw->pulsed->playing_file = -1;
1974 mainw->pulsed->fd = -1;
1975 } else {
1976 while (mainw->pulsed->playing_file > -1 || mainw->pulsed->fd > 0) {
1977 sched_yield();
1978 lives_usleep(prefs->sleep_time);
1979 }
1980 pulse_driver_cork(mainw->pulsed);
1981 }
1982 } else {
1983 pulse_driver_cork(mainw->pulsed);
1984 }
1985 }
1986 }
1987 #endif
1988 }
1989
1990
preview_aud_vol(void)1991 void preview_aud_vol(void) {
1992 float ovol = cfile->vol;
1993 cfile->vol = (float)mainw->fx1_val;
1994 preview_audio();
1995 cfile->vol = ovol;
1996 mainw->cancelled = CANCEL_NONE;
1997 mainw->error = FALSE;
1998 }
1999
2000
adjust_clip_volume(int fileno,float newvol,boolean make_backup)2001 boolean adjust_clip_volume(int fileno, float newvol, boolean make_backup) {
2002 double dvol = (double)newvol;
2003 if (make_backup) {
2004 char *com = lives_strdup_printf("%s backup_audio \"%s\"", prefs->backend_sync, cfile->handle);
2005 lives_system(com, FALSE);
2006 lives_free(com);
2007 if (THREADVAR(com_failed)) {
2008 THREADVAR(com_failed) = FALSE;
2009 return FALSE;
2010 }
2011 }
2012 aud_fade(fileno, 0., CLIP_AUDIO_TIME(fileno), dvol, dvol);
2013 return TRUE;
2014 }
2015
2016
2017 #ifdef ENABLE_JACK
jack_rec_audio_to_clip(int fileno,int old_file,lives_rec_audio_type_t rec_type)2018 void jack_rec_audio_to_clip(int fileno, int old_file, lives_rec_audio_type_t rec_type) {
2019 // open audio file for writing
2020 lives_clip_t *outfile;
2021
2022 boolean jackd_read_started = (mainw->jackd_read != NULL);
2023
2024 int retval;
2025
2026 // should we set is_paused ? (yes)
2027 // should we reset time (no)
2028
2029 if (fileno == -1) {
2030 // respond to external audio, but do not record it (yet)
2031 if (!mainw->jackd_read) {
2032 mainw->jackd_read = jack_get_driver(0, FALSE);
2033 mainw->jackd_read->playing_file = fileno;
2034 mainw->jackd_read->reverse_endian = FALSE;
2035 mainw->jackd_read->frames_written = 0;
2036
2037 // start jack "recording"
2038 jack_create_client_reader(mainw->jackd_read);
2039 jack_read_driver_activate(mainw->jackd_read, FALSE);
2040 }
2041 return;
2042 }
2043
2044 outfile = mainw->files[fileno];
2045
2046 if (mainw->aud_rec_fd == -1) {
2047 char *outfilename = lives_get_audio_file_name(fileno);
2048 do {
2049 retval = 0;
2050 mainw->aud_rec_fd = lives_open3(outfilename, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
2051 if (mainw->aud_rec_fd < 0) {
2052 retval = do_write_failed_error_s_with_retry(outfilename, lives_strerror(errno));
2053 if (retval == LIVES_RESPONSE_CANCEL) {
2054 lives_free(outfilename);
2055 return;
2056 }
2057 }
2058 } while (retval == LIVES_RESPONSE_RETRY);
2059 lives_free(outfilename);
2060 if (fileno == mainw->ascrap_file) mainw->files[mainw->ascrap_file]->cb_src = mainw->aud_rec_fd;
2061 }
2062
2063 if (rec_type == RECA_GENERATED) {
2064 mainw->jackd->playing_file = fileno;
2065 } else {
2066 if (!jackd_read_started) {
2067 mainw->jackd_read = jack_get_driver(0, FALSE);
2068 /* jack_create_client_reader(mainw->jackd_read); */
2069 /* jack_read_driver_activate(mainw->jackd_read, FALSE); */
2070 /* mainw->jackd_read->is_paused = TRUE; */
2071 /* jack_time_reset(mainw->jackd_read, 0); */
2072 mainw->jackd_read->playing_file = fileno;
2073 mainw->jackd_read->frames_written = 0;
2074 }
2075 mainw->jackd_read->playing_file = fileno;
2076 }
2077
2078 if (rec_type == RECA_EXTERNAL || rec_type == RECA_GENERATED) {
2079 int asigned;
2080 int aendian;
2081 off_t fsize = get_file_size(mainw->aud_rec_fd);
2082
2083 if (rec_type == RECA_EXTERNAL) {
2084 mainw->jackd_read->reverse_endian = FALSE;
2085
2086 outfile->arate = outfile->arps = mainw->jackd_read->sample_in_rate;
2087 outfile->achans = mainw->jackd_read->num_input_channels;
2088
2089 outfile->asampsize = 16;
2090 outfile->signed_endian = get_signed_endian(TRUE, TRUE);
2091
2092 asigned = !(outfile->signed_endian & AFORM_UNSIGNED);
2093 aendian = !(outfile->signed_endian & AFORM_BIG_ENDIAN);
2094
2095 mainw->jackd_read->frames_written = fsize / (outfile->achans * (outfile->asampsize >> 3));
2096 } else {
2097 mainw->jackd->reverse_endian = FALSE;
2098 outfile->arate = outfile->arps = mainw->jackd->sample_out_rate;
2099 outfile->achans = mainw->jackd->num_output_channels;
2100
2101 outfile->asampsize = 16;
2102 outfile->signed_endian = get_signed_endian(TRUE, TRUE);
2103
2104 asigned = !(outfile->signed_endian & AFORM_UNSIGNED);
2105 aendian = !(outfile->signed_endian & AFORM_BIG_ENDIAN);
2106 }
2107
2108 save_clip_value(fileno, CLIP_DETAILS_ACHANS, &outfile->achans);
2109 save_clip_value(fileno, CLIP_DETAILS_ARATE, &outfile->arps);
2110 save_clip_value(fileno, CLIP_DETAILS_PB_ARATE, &outfile->arate);
2111 save_clip_value(fileno, CLIP_DETAILS_ASAMPS, &outfile->asampsize);
2112 save_clip_value(fileno, CLIP_DETAILS_AENDIAN, &aendian);
2113 save_clip_value(fileno, CLIP_DETAILS_ASIGNED, &asigned);
2114 } else {
2115 int out_bendian = outfile->signed_endian & AFORM_BIG_ENDIAN;
2116
2117 if ((!out_bendian && (capable->byte_order == LIVES_BIG_ENDIAN)) ||
2118 (out_bendian && (capable->byte_order == LIVES_LITTLE_ENDIAN)))
2119 mainw->jackd_read->reverse_endian = TRUE;
2120 else mainw->jackd_read->reverse_endian = FALSE;
2121
2122 // start jack recording
2123 /* mainw->jackd_read = jack_get_driver(0, FALSE); */
2124 /* jack_create_client_reader(mainw->jackd_read); */
2125 jack_read_driver_activate(mainw->jackd_read, TRUE);
2126 /* mainw->jackd_read->is_paused = TRUE; */
2127 /* jack_time_reset(mainw->jackd_read, 0); */
2128 }
2129
2130 // in grab window mode, just return, we will call rec_audio_end on playback end
2131 if (rec_type == RECA_WINDOW_GRAB || rec_type == RECA_EXTERNAL || rec_type == RECA_GENERATED) return;
2132
2133 mainw->cancelled = CANCEL_NONE;
2134 mainw->cancel_type = CANCEL_SOFT;
2135 // show countdown/stop dialog
2136 mainw->suppress_dprint = FALSE;
2137 d_print(_("Recording audio..."));
2138 mainw->suppress_dprint = TRUE;
2139 if (rec_type == RECA_NEW_CLIP) {
2140 mainw->jackd_read->in_use = TRUE;
2141 do_auto_dialog(_("Recording audio..."), 1);
2142 } else {
2143 int current_file = mainw->current_file;
2144 mainw->current_file = old_file;
2145 mainw->jackd_read->is_paused = TRUE;
2146 mainw->jackd_read->in_use = TRUE;
2147 on_playsel_activate(NULL, NULL);
2148 mainw->current_file = current_file;
2149 }
2150 mainw->cancel_type = CANCEL_KILL;
2151 jack_rec_audio_end(!prefs->perm_audio_reader, TRUE);
2152 }
2153
2154
jack_rec_audio_end(boolean close_device,boolean close_fd)2155 void jack_rec_audio_end(boolean close_device, boolean close_fd) {
2156 // recording ended
2157
2158 pthread_mutex_lock(&mainw->audio_filewriteend_mutex);
2159 if (mainw->jackd_read->playing_file > -1)
2160 jack_flush_read_data(0, NULL);
2161
2162 if (close_device) {
2163 // stop recording
2164 if (mainw->jackd_read) jack_close_device(mainw->jackd_read);
2165 mainw->jackd_read = NULL;
2166 } else {
2167 mainw->jackd_read->in_use = FALSE;
2168 mainw->jackd_read->playing_file = -1;
2169 }
2170 pthread_mutex_unlock(&mainw->audio_filewriteend_mutex);
2171
2172 if (close_fd && mainw->aud_rec_fd != -1) {
2173 // close file
2174 close(mainw->aud_rec_fd);
2175 mainw->aud_rec_fd = -1;
2176 }
2177 }
2178 #endif
2179
2180
2181 #ifdef HAVE_PULSE_AUDIO
2182
pulse_rec_audio_to_clip(int fileno,int old_file,lives_rec_audio_type_t rec_type)2183 void pulse_rec_audio_to_clip(int fileno, int old_file, lives_rec_audio_type_t rec_type) {
2184 // open audio file for writing
2185 lives_clip_t *outfile;
2186 int retval;
2187
2188 if (fileno == -1) {
2189 if (!mainw->pulsed_read) {
2190 mainw->pulsed_read = pulse_get_driver(FALSE);
2191 mainw->pulsed_read->playing_file = -1;
2192 mainw->pulsed_read->frames_written = 0;
2193 mainw->pulsed_read->reverse_endian = FALSE;
2194 mainw->aud_rec_fd = -1;
2195 pulse_driver_activate(mainw->pulsed_read);
2196 }
2197 return;
2198 }
2199
2200 outfile = mainw->files[fileno];
2201
2202 if (mainw->aud_rec_fd == -1) {
2203 char *outfilename = lives_get_audio_file_name(fileno);
2204 do {
2205 retval = 0;
2206 mainw->aud_rec_fd = lives_open3(outfilename, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
2207 if (mainw->aud_rec_fd < 0) {
2208 retval = do_write_failed_error_s_with_retry(outfilename, lives_strerror(errno));
2209 if (retval == LIVES_RESPONSE_CANCEL) {
2210 lives_free(outfilename);
2211 return;
2212 }
2213 }
2214 } while (retval == LIVES_RESPONSE_RETRY);
2215 lives_free(outfilename);
2216 if (fileno == mainw->ascrap_file) {
2217 mainw->files[mainw->ascrap_file]->cb_src = mainw->aud_rec_fd;
2218 /* if (mainw->pulsed_read) {
2219 // flush all data from buffer; this seems like the only way
2220 void *data;
2221 size_t rbytes;
2222 pa_mloop_lock();
2223 do {
2224 pa_stream_peek(mainw->pulsed_read->pstream, (const void **)&data, &rbytes);
2225 if (rbytes > 0) pa_stream_drop(mainw->pulsed_read->pstream);
2226 } while (rbytes > 0);
2227 pa_mloop_unlock();
2228 }*/
2229 }
2230 }
2231
2232 if (rec_type == RECA_GENERATED) {
2233 mainw->pulsed->playing_file = fileno;
2234 } else {
2235 mainw->pulsed_read = pulse_get_driver(FALSE);
2236 mainw->pulsed_read->playing_file = fileno;
2237 mainw->pulsed_read->frames_written = 0;
2238 }
2239
2240 if (rec_type == RECA_EXTERNAL || rec_type == RECA_GENERATED) {
2241 int asigned;
2242 int aendian;
2243 off_t fsize = get_file_size(mainw->aud_rec_fd);
2244
2245 if (rec_type == RECA_EXTERNAL) {
2246 mainw->pulsed_read->reverse_endian = FALSE;
2247
2248 pulse_driver_activate(mainw->pulsed_read);
2249
2250 outfile->arate = outfile->arps = mainw->pulsed_read->out_arate;
2251 outfile->achans = mainw->pulsed_read->out_achans;
2252 outfile->asampsize = mainw->pulsed_read->out_asamps;
2253 outfile->signed_endian = get_signed_endian(mainw->pulsed_read->out_signed != AFORM_UNSIGNED,
2254 mainw->pulsed_read->out_endian != AFORM_BIG_ENDIAN);
2255
2256 asigned = !(outfile->signed_endian & AFORM_UNSIGNED);
2257 aendian = !(outfile->signed_endian & AFORM_BIG_ENDIAN);
2258
2259 mainw->pulsed_read->frames_written = fsize / (outfile->achans * (outfile->asampsize >> 3));
2260 } else {
2261 mainw->pulsed->reverse_endian = FALSE;
2262 outfile->arate = outfile->arps = mainw->pulsed->out_arate;
2263 outfile->achans = mainw->pulsed->out_achans;
2264 outfile->asampsize = mainw->pulsed->out_asamps;
2265 outfile->signed_endian = get_signed_endian(mainw->pulsed->out_signed != AFORM_UNSIGNED,
2266 mainw->pulsed->out_endian != AFORM_BIG_ENDIAN);
2267
2268 asigned = !(outfile->signed_endian & AFORM_UNSIGNED);
2269 aendian = !(outfile->signed_endian & AFORM_BIG_ENDIAN);
2270 }
2271
2272 outfile->header_version = LIVES_CLIP_HEADER_VERSION;
2273 save_clip_value(fileno, CLIP_DETAILS_HEADER_VERSION, &outfile->header_version);
2274 save_clip_value(fileno, CLIP_DETAILS_ACHANS, &outfile->achans);
2275 save_clip_value(fileno, CLIP_DETAILS_ARATE, &outfile->arps);
2276 save_clip_value(fileno, CLIP_DETAILS_PB_ARATE, &outfile->arate);
2277 save_clip_value(fileno, CLIP_DETAILS_ASAMPS, &outfile->asampsize);
2278 save_clip_value(fileno, CLIP_DETAILS_AENDIAN, &aendian);
2279 save_clip_value(fileno, CLIP_DETAILS_ASIGNED, &asigned);
2280 } else {
2281 int out_bendian = outfile->signed_endian & AFORM_BIG_ENDIAN;
2282
2283 if ((!out_bendian && (capable->byte_order == LIVES_BIG_ENDIAN)) ||
2284 (out_bendian && (capable->byte_order == LIVES_LITTLE_ENDIAN)))
2285 mainw->pulsed_read->reverse_endian = TRUE;
2286 else mainw->pulsed_read->reverse_endian = FALSE;
2287
2288 // start pulse recording
2289 pulse_driver_activate(mainw->pulsed_read);
2290 }
2291
2292 // in grab window mode, just return, we will call rec_audio_end on playback end
2293 if (rec_type == RECA_WINDOW_GRAB || rec_type == RECA_EXTERNAL || rec_type == RECA_GENERATED) return;
2294
2295 mainw->cancelled = CANCEL_NONE;
2296 mainw->cancel_type = CANCEL_SOFT;
2297 // show countdown/stop dialog
2298 mainw->suppress_dprint = FALSE;
2299 d_print(_("Recording audio..."));
2300 mainw->suppress_dprint = TRUE;
2301 if (rec_type == RECA_NEW_CLIP) {
2302 mainw->pulsed_read->in_use = TRUE;
2303 do_auto_dialog(_("Recording audio..."), 1);
2304 } else {
2305 int current_file = mainw->current_file;
2306 mainw->current_file = old_file;
2307 mainw->pulsed_read->is_paused = TRUE;
2308 mainw->pulsed_read->in_use = TRUE;
2309 on_playsel_activate(NULL, NULL);
2310 mainw->current_file = current_file;
2311 }
2312 mainw->cancel_type = CANCEL_KILL;
2313 pulse_rec_audio_end(!prefs->perm_audio_reader, TRUE);
2314 }
2315
2316
pulse_rec_audio_end(boolean close_device,boolean close_fd)2317 void pulse_rec_audio_end(boolean close_device, boolean close_fd) {
2318 // recording ended
2319
2320 // stop recording
2321
2322 if (mainw->pulsed_read) {
2323 pthread_mutex_lock(&mainw->audio_filewriteend_mutex);
2324 if (mainw->pulsed_read->playing_file > -1)
2325 pulse_flush_read_data(mainw->pulsed_read, mainw->pulsed_read->playing_file, 0, mainw->pulsed_read->reverse_endian, NULL);
2326
2327 if (close_device) pulse_close_client(mainw->pulsed_read);
2328
2329 if (close_device) mainw->pulsed_read = NULL;
2330 else {
2331 mainw->pulsed_read->in_use = FALSE;
2332 mainw->pulsed_read->playing_file = -1;
2333 }
2334 pthread_mutex_unlock(&mainw->audio_filewriteend_mutex);
2335 }
2336
2337 if (mainw->aud_rec_fd != -1 && close_fd) {
2338 // close file
2339 close(mainw->aud_rec_fd);
2340 mainw->aud_rec_fd = -1;
2341 }
2342 }
2343
2344 #endif
2345
2346 /////////////////////////////////////////////////////////////////
2347
2348 // playback via memory buffers (e.g. in multitrack)
2349
2350 ////////////////////////////////////////////////////////////////
2351 /// TODO - move these to events.c
2352
resize_audstate(lives_audio_track_state_t * ostate,int nostate,int nstate)2353 static lives_audio_track_state_t *resize_audstate(lives_audio_track_state_t *ostate, int nostate, int nstate) {
2354 // increase the element size of the audstate array (ostate)
2355 // from nostate elements to nstate elements
2356 lives_audio_track_state_t *audstate = (lives_audio_track_state_t *)lives_calloc(nstate, sizeof(lives_audio_track_state_t));
2357 int n = MIN(nostate, nstate);
2358 if (n > 0)
2359 lives_memcpy(audstate, ostate, n * sizeof(lives_audio_track_state_t));
2360 lives_freep((void **)&ostate);
2361 return audstate;
2362 }
2363
2364
aframe_to_atstate_inner(weed_plant_t * event,int * ntracks)2365 static lives_audio_track_state_t *aframe_to_atstate_inner(weed_plant_t *event, int *ntracks) {
2366 // parse an audio frame, and set the track file, seek and velocity values
2367 int num_aclips = 0, atrack;
2368 int *aclips = NULL;
2369 double *aseeks = NULL;
2370 int naudstate = 0;
2371 lives_audio_track_state_t *atstate = NULL;
2372
2373 int i;
2374
2375 int btoffs = mainw->multitrack ? mainw->multitrack->opts.back_audio_tracks : 1;
2376 num_aclips = weed_frame_event_get_audio_tracks(event, &aclips, &aseeks);
2377 for (i = 0; i < num_aclips; i += 2) {
2378 if (aclips[i + 1] > 0) { // else ignore
2379 atrack = aclips[i];
2380 if (atrack + btoffs >= naudstate - 1) {
2381 atstate = resize_audstate(atstate, naudstate, atrack + btoffs + 2);
2382 naudstate = atrack + btoffs + 1;
2383 atstate[naudstate].afile = -1;
2384 }
2385 atstate[atrack + btoffs].afile = aclips[i + 1];
2386 atstate[atrack + btoffs].seek = aseeks[i];
2387 atstate[atrack + btoffs].vel = aseeks[i + 1];
2388 }
2389 }
2390
2391 lives_freep((void **)&aclips);
2392 lives_freep((void **)&aseeks);
2393
2394 if (ntracks) *ntracks = num_aclips;
2395
2396 return atstate;
2397 }
2398
2399
aframe_to_atstate(weed_plant_t * event)2400 LIVES_LOCAL_INLINE lives_audio_track_state_t *aframe_to_atstate(weed_plant_t *event) {
2401 return aframe_to_atstate_inner(event, NULL);
2402 }
2403
2404
audio_frame_to_atstate(weed_event_t * event,int * ntracks)2405 LIVES_GLOBAL_INLINE lives_audio_track_state_t *audio_frame_to_atstate(weed_event_t *event, int *ntracks) {
2406 return aframe_to_atstate_inner(event, ntracks);
2407 }
2408
2409
2410 /**
2411 @brief get audio (and optionally video) state at timecode tc OR before event st_event
2412
2413 if st_event is not NULL, we get the state just prior to it
2414 (state being effects and filter maps, audio tracks / positions)
2415
2416 if st_event is NULL, this is a continuation, and we get the audio state only at timecode tc
2417 similar to quantise_events(), except we don't produce output frames
2418 */
get_audio_and_effects_state_at(weed_plant_t * event_list,weed_plant_t * st_event,weed_timecode_t fill_tc,int what_to_get,boolean exact)2419 lives_audio_track_state_t *get_audio_and_effects_state_at(weed_plant_t *event_list, weed_plant_t *st_event,
2420 weed_timecode_t fill_tc, int what_to_get, boolean exact) {
2421 // if exact is set, we must rewind back to first active stateful effect,
2422 // and play forwards from there (not yet implemented - TODO)
2423 lives_audio_track_state_t *atstate = NULL, *audstate = NULL;
2424 weed_timecode_t last_tc = 0;
2425 weed_event_t *event, *nevent;
2426 weed_event_t *deinit_event;
2427 int nfiles, nnfiles, etype;
2428
2429 // gets effects state immediately prior to start_event. (initing any effects which should be active, and applying param changes
2430 // if not in multrack)
2431
2432 // optionally: gets audio state, sets atstate[0].tc
2433 // and initialises audio buffers
2434
2435 if (fill_tc == 0) {
2436 if (what_to_get != LIVES_PREVIEW_TYPE_AUDIO_ONLY)
2437 mainw->filter_map = NULL;
2438 if (what_to_get != LIVES_PREVIEW_TYPE_VIDEO_ONLY)
2439 mainw->afilter_map = NULL;
2440 event = get_first_event(event_list);
2441 } else {
2442 event = st_event;
2443 st_event = NULL;
2444 }
2445
2446 while ((st_event && event != st_event) || (!st_event && get_event_timecode(event) < fill_tc)) {
2447 etype = weed_event_get_type(event);
2448 if (what_to_get == LIVES_PREVIEW_TYPE_VIDEO_AUDIO || (etype != 1 && etype != 5)) {
2449 switch (etype) {
2450 case WEED_EVENT_TYPE_FILTER_MAP:
2451 if (what_to_get != LIVES_PREVIEW_TYPE_AUDIO_ONLY)
2452 mainw->filter_map = event;
2453 if (what_to_get != LIVES_PREVIEW_TYPE_VIDEO_ONLY) {
2454 mainw->afilter_map = event;
2455 }
2456 break;
2457 case WEED_EVENT_TYPE_FILTER_INIT:
2458 deinit_event = weed_get_plantptr_value(event, WEED_LEAF_DEINIT_EVENT, NULL);
2459 if (!deinit_event || get_event_timecode(deinit_event) >= fill_tc) {
2460 // this effect should be activated
2461 if (what_to_get != LIVES_PREVIEW_TYPE_AUDIO_ONLY)
2462 process_events(event, FALSE, get_event_timecode(event));
2463 if (what_to_get != LIVES_PREVIEW_TYPE_VIDEO_ONLY)
2464 process_events(event, TRUE, get_event_timecode(event));
2465 /// TODO: if exact && non-stateless, silently process audio / video until st_event
2466 }
2467 break;
2468 case WEED_EVENT_TYPE_FILTER_DEINIT:
2469 if (what_to_get == LIVES_PREVIEW_TYPE_AUDIO_ONLY) {
2470 weed_event_t *init_event = weed_get_voidptr_value((weed_plant_t *)event, WEED_LEAF_INIT_EVENT, NULL);
2471 if (get_event_timecode(init_event) >= last_tc) break;
2472 process_events(event, TRUE, get_event_timecode(event));
2473 }
2474 break;
2475 case WEED_EVENT_TYPE_PARAM_CHANGE:
2476 if (!mainw->multitrack) {
2477 weed_event_t *init_event = weed_get_voidptr_value((weed_plant_t *)event, WEED_LEAF_INIT_EVENT, NULL);
2478 deinit_event = weed_get_plantptr_value(init_event, WEED_LEAF_DEINIT_EVENT, NULL);
2479 if (deinit_event && get_event_timecode(deinit_event) < fill_tc) break;
2480
2481 if (weed_plant_has_leaf((weed_plant_t *)init_event, WEED_LEAF_HOST_TAG)) {
2482 char *key_string = weed_get_string_value((weed_plant_t *)init_event, WEED_LEAF_HOST_TAG, NULL);
2483 int key = atoi(key_string);
2484 char *filter_name = weed_get_string_value((weed_plant_t *)init_event, WEED_LEAF_FILTER, NULL);
2485 int idx = weed_get_idx_for_hashname(filter_name, TRUE);
2486 weed_event_t *filter = get_weed_filter(idx), *inst;
2487 lives_free(filter_name);
2488 lives_free(key_string);
2489
2490 if (!is_pure_audio(filter, FALSE)) {
2491 if (what_to_get == LIVES_PREVIEW_TYPE_AUDIO_ONLY)
2492 break;
2493 } else {
2494 if (what_to_get == LIVES_PREVIEW_TYPE_VIDEO_ONLY)
2495 break;
2496 }
2497 if ((inst = rte_keymode_get_instance(key + 1, 0)) != NULL) {
2498 int pnum = weed_get_int_value(event, WEED_LEAF_INDEX, NULL);
2499 weed_plant_t *param = weed_inst_in_param(inst, pnum, FALSE, FALSE);
2500 weed_leaf_dup(param, event, WEED_LEAF_VALUE);
2501 }
2502 }
2503 }
2504 break;
2505 case WEED_EVENT_TYPE_FRAME:
2506 if (what_to_get != LIVES_PREVIEW_TYPE_VIDEO_AUDIO) break;
2507
2508 if (WEED_EVENT_IS_AUDIO_FRAME(event)) {
2509 /// update audio state
2510 atstate = aframe_to_atstate(event);
2511 if (!audstate) {
2512 audstate = atstate;
2513 last_tc = get_event_timecode(event);
2514 } else {
2515 // have an existing audio state, update with current
2516 weed_timecode_t delta = get_event_timecode(event) - last_tc;
2517 for (nfiles = 0; audstate[nfiles].afile != -1; nfiles++) {
2518 if (delta > 0) {
2519 // increase seek values up to current frame
2520 audstate[nfiles].seek += audstate[nfiles].vel * delta / TICKS_PER_SECOND_DBL;
2521 }
2522 }
2523 last_tc += delta;
2524 for (nnfiles = 0; atstate[nnfiles].afile != -1; nnfiles++);
2525 if (nnfiles > nfiles) {
2526 audstate = resize_audstate(audstate, nfiles, nnfiles + 1);
2527 audstate[nnfiles].afile = -1;
2528 }
2529
2530 for (int i = 0; i < nnfiles; i++) {
2531 if (atstate[i].afile > 0) {
2532 audstate[i].afile = atstate[i].afile;
2533 audstate[i].seek = atstate[i].seek;
2534 audstate[i].vel = atstate[i].vel;
2535 }
2536 }
2537 lives_free(atstate);
2538 }
2539 }
2540 break;
2541 default:
2542 break;
2543 }
2544 }
2545 nevent = get_next_event(event);
2546 if (!nevent) break;
2547 event = nevent;
2548 if (what_to_get == LIVES_PREVIEW_TYPE_AUDIO_ONLY && WEED_EVENT_IS_AUDIO_FRAME(event)) break;
2549 }
2550 if (what_to_get == LIVES_PREVIEW_TYPE_VIDEO_AUDIO) {
2551 if (audstate) {
2552 weed_timecode_t delta = get_event_timecode(event) - last_tc;
2553 if (delta > 0) {
2554 for (nfiles = 0; audstate[nfiles].afile != -1; nfiles++) {
2555 // increase seek values up to current frame
2556 audstate[nfiles].seek += audstate[nfiles].vel * delta / TICKS_PER_SECOND_DBL;
2557 // *INDENT-OFF*
2558 }}}}
2559 // *INDENT-ON*
2560
2561 if (what_to_get != LIVES_PREVIEW_TYPE_VIDEO_ONLY)
2562 mainw->audio_event = event;
2563 return audstate;
2564 }
2565
2566
fill_abuffer_from(lives_audio_buf_t * abuf,weed_plant_t * event_list,weed_plant_t * st_event,boolean exact)2567 void fill_abuffer_from(lives_audio_buf_t *abuf, weed_plant_t *event_list, weed_plant_t *st_event, boolean exact) {
2568 // fill audio buffer with audio samples, using event_list as a guide
2569 // if st_event!=NULL, that is our start event, and we will calculate the audio state at that
2570 // point
2571
2572 // otherwise, we continue from where we left off the last time
2573
2574 // all we really do here is set from_files, aseeks and avels arrays and call render_audio_segment
2575 // effects are ignored here; they are applied in smaller chunks in render_audio_segment, so that parameter interpolation can be done
2576
2577 lives_audio_track_state_t *atstate = NULL;
2578 double chvols[MAX_AUDIO_TRACKS]; // TODO - use list
2579
2580 static weed_timecode_t last_tc, tc;
2581 static weed_timecode_t fill_tc;
2582 static weed_plant_t *event;
2583 static int nfiles;
2584
2585 static int *from_files = NULL;
2586 static double *aseeks = NULL, *avels = NULL;
2587
2588 int i;
2589
2590 if (!abuf) return;
2591
2592 abuf->samples_filled = 0; // write fill level of buffer
2593 abuf->start_sample = 0; // read level
2594
2595 if (st_event) {
2596 // this is only called for the first buffered read
2597 //
2598 event = st_event;
2599 last_tc = get_event_timecode(event);
2600
2601 lives_freep((void **)&from_files);
2602 lives_freep((void **)&avels);
2603 lives_freep((void **)&aseeks);
2604
2605 if (mainw->multitrack && mainw->multitrack->avol_init_event)
2606 nfiles = weed_leaf_num_elements(mainw->multitrack->avol_init_event, WEED_LEAF_IN_TRACKS);
2607
2608 else nfiles = 1;
2609
2610 from_files = (int *)lives_calloc(nfiles, sizint);
2611 avels = (double *)lives_calloc(nfiles, sizdbl);
2612 aseeks = (double *)lives_calloc(nfiles, sizdbl);
2613
2614 for (i = 0; i < nfiles; i++) {
2615 from_files[i] = 0;
2616 avels[i] = aseeks[i] = 0.;
2617 }
2618
2619 // get audio and fx state at pt immediately before st_event
2620 atstate = get_audio_and_effects_state_at(event_list, event, 0, LIVES_PREVIEW_TYPE_VIDEO_AUDIO, exact);
2621
2622 if (atstate) {
2623 for (i = 0; atstate[i].afile != -1; i++) {
2624 if (atstate[i].afile > 0) {
2625 from_files[i] = atstate[i].afile;
2626 avels[i] = atstate[i].vel;
2627 aseeks[i] = atstate[i].seek;
2628 }
2629 }
2630 lives_free(atstate);
2631 }
2632 }
2633
2634 if (mainw->multitrack) {
2635 // get channel volumes from the mixer
2636 for (i = 0; i < nfiles; i++) {
2637 if (mainw->multitrack && mainw->multitrack->audio_vols) {
2638 chvols[i] = (double)LIVES_POINTER_TO_INT(lives_list_nth_data(mainw->multitrack->audio_vols, i)) / ONE_MILLION_DBL;
2639 }
2640 }
2641 } else chvols[0] = 1.;
2642
2643 fill_tc = last_tc + fabs((double)(abuf->samp_space) / (double)abuf->arate * TICKS_PER_SECOND_DBL);
2644
2645 // continue until we have a full buffer
2646 // if we get an audio frame we render up to that point
2647 // then we render what is left to fill abuf
2648 while (event && (tc = get_event_timecode(event)) < fill_tc) {
2649 if (WEED_EVENT_IS_AUDIO_FRAME(event)) {
2650 // got next audio frame
2651 render_audio_segment(nfiles, from_files, -1, avels, aseeks, last_tc, tc, chvols, 1., 1., abuf);
2652
2653 /* for (i = 0; i < nfiles; i++) { */
2654 /* // increase seek values */
2655 /* aseeks[i] += avels[i] * (tc - last_tc) / TICKS_PER_SECOND_DBL; */
2656 /* } */
2657
2658 last_tc = tc;
2659 // process audio updates at this frame
2660 atstate = aframe_to_atstate(event);
2661
2662 if (atstate) {
2663 int nnfiles;
2664 for (nnfiles = 0; atstate[nnfiles].afile != -1; nnfiles++);
2665 for (i = 0; i < nnfiles; i++) {
2666 if (atstate[i].afile > 0) {
2667 from_files[i] = atstate[i].afile;
2668 avels[i] = atstate[i].vel;
2669 aseeks[i] = atstate[i].seek;
2670 }
2671 }
2672 lives_free(atstate);
2673 }
2674 }
2675 event = get_next_audio_frame_event(event);
2676 }
2677
2678 if (last_tc < fill_tc) {
2679 // fill the rest of the buffer
2680 /* if (nfiles == 0) */
2681 /* render_audio_segment(1, NULL, -1, NULL, NULL, last_tc, fill_tc, chvols, 0., 0., abuf); */
2682 //else
2683 render_audio_segment(nfiles, from_files, -1, avels, aseeks, last_tc, fill_tc, chvols, 1., 1., abuf);
2684 /* for (i = 0; i < nfiles; i++) { */
2685 /* // increase seek values */
2686 /* aseeks[i] += avels[i] * (fill_tc - last_tc) / TICKS_PER_SECOND_DBL; */
2687 /* } */
2688 }
2689
2690 if (THREADVAR(read_failed) > 0) {
2691 THREADVAR(read_failed) = 0;
2692 do_read_failed_error_s(THREADVAR(read_failed_file), NULL);
2693 }
2694
2695 mainw->write_abuf++;
2696 if (mainw->write_abuf >= prefs->num_rtaudiobufs) mainw->write_abuf = 0;
2697
2698 last_tc = fill_tc;
2699
2700 pthread_mutex_lock(&mainw->abuf_mutex);
2701 if (mainw->abufs_to_fill > 0) {
2702 mainw->abufs_to_fill--;
2703 }
2704 pthread_mutex_unlock(&mainw->abuf_mutex);
2705 }
2706
2707
init_jack_audio_buffers(int achans,int arate,boolean exact)2708 void init_jack_audio_buffers(int achans, int arate, boolean exact) {
2709 #ifdef ENABLE_JACK
2710
2711 int chan;
2712
2713 mainw->jackd->abufs = (lives_audio_buf_t **)lives_calloc(prefs->num_rtaudiobufs, sizeof(lives_audio_buf_t *));
2714
2715 for (int i = 0; i < prefs->num_rtaudiobufs; i++) {
2716 mainw->jackd->abufs[i] = (lives_audio_buf_t *)lives_calloc(1, sizeof(lives_audio_buf_t));
2717 mainw->jackd->abufs[i]->out_achans = achans;
2718 mainw->jackd->abufs[i]->arate = arate;
2719 mainw->jackd->abufs[i]->samp_space = XSAMPLES / prefs->num_rtaudiobufs;
2720 mainw->jackd->abufs[i]->bufferf = (float **)lives_calloc(achans, sizeof(float *));
2721 for (chan = 0; chan < achans; chan++) {
2722 mainw->jackd->abufs[i]->bufferf[chan] = (float *)lives_calloc_safety(XSAMPLES / prefs->num_rtaudiobufs, sizeof(float));
2723 }
2724 }
2725 #endif
2726 }
2727
2728
init_pulse_audio_buffers(int achans,int arate,boolean exact)2729 void init_pulse_audio_buffers(int achans, int arate, boolean exact) {
2730 #ifdef HAVE_PULSE_AUDIO
2731 mainw->pulsed->abufs = (lives_audio_buf_t **)lives_calloc(prefs->num_rtaudiobufs, sizeof(lives_audio_buf_t *));
2732
2733 for (int i = 0; i < prefs->num_rtaudiobufs; i++) {
2734 mainw->pulsed->abufs[i] = (lives_audio_buf_t *)lives_calloc(1, sizeof(lives_audio_buf_t));
2735
2736 mainw->pulsed->abufs[i]->out_achans = achans;
2737 mainw->pulsed->abufs[i]->arate = arate;
2738 mainw->pulsed->abufs[i]->start_sample = 0;
2739 mainw->pulsed->abufs[i]->samp_space = XSAMPLES / prefs->num_rtaudiobufs; // samp_space here is in stereo samples
2740 mainw->pulsed->abufs[i]->buffer16 = (short **)lives_calloc(1, sizeof(short *));
2741 mainw->pulsed->abufs[i]->buffer16[0] = (short *)lives_calloc_safety(XSAMPLES / prefs->num_rtaudiobufs,
2742 achans * sizeof(short));
2743 }
2744 #endif
2745 }
2746
2747
free_jack_audio_buffers(void)2748 void free_jack_audio_buffers(void) {
2749 #ifdef ENABLE_JACK
2750 int chan;
2751
2752 if (!mainw->jackd || !mainw->jackd->abufs) return;
2753
2754 for (int i = 0; i < prefs->num_rtaudiobufs; i++) {
2755 if (mainw->jackd->abufs[i]) {
2756 for (chan = 0; chan < mainw->jackd->abufs[i]->out_achans; chan++) {
2757 lives_free(mainw->jackd->abufs[i]->bufferf[chan]);
2758 }
2759 lives_free(mainw->jackd->abufs[i]->bufferf);
2760 lives_free(mainw->jackd->abufs[i]);
2761 }
2762 }
2763 lives_free(mainw->jackd->abufs);
2764 #endif
2765 }
2766
2767
free_pulse_audio_buffers(void)2768 void free_pulse_audio_buffers(void) {
2769 #ifdef HAVE_PULSE_AUDIO
2770
2771 if (!mainw->pulsed || !mainw->pulsed->abufs) return;
2772
2773 for (int i = 0; i < prefs->num_rtaudiobufs; i++) {
2774 if (mainw->pulsed->abufs[i]) {
2775 lives_free(mainw->pulsed->abufs[i]->buffer16[0]);
2776 lives_free(mainw->pulsed->abufs[i]->buffer16);
2777 lives_free(mainw->pulsed->abufs[i]);
2778 }
2779 }
2780 lives_free(mainw->pulsed->abufs);
2781 #endif
2782 }
2783
2784
avsync_force(void)2785 LIVES_GLOBAL_INLINE void avsync_force(void) {
2786 #ifdef RESEEK_ENABLE
2787 /// force realignment of video and audio at current file->frameno / player->seek_pos
2788 if (mainw->foreign || !LIVES_IS_PLAYING || prefs->audio_src == AUDIO_SRC_EXT || prefs->force_system_clock
2789 || (mainw->event_list && !(mainw->record || mainw->record_paused)) || prefs->audio_player == AUD_PLAYER_NONE
2790 || !is_realtime_aplayer(prefs->audio_player)) {
2791 mainw->video_seek_ready = mainw->audio_seek_ready = TRUE;
2792 return;
2793 }
2794
2795 if (!pthread_mutex_trylock(&mainw->avseek_mutex)) {
2796 if (mainw->audio_seek_ready && mainw->video_seek_ready) {
2797 mainw->video_seek_ready = mainw->audio_seek_ready = FALSE;
2798 mainw->force_show = TRUE;
2799 mainw->startticks = mainw->currticks = lives_get_current_playback_ticks(mainw->origsecs, mainw->orignsecs, NULL);
2800 }
2801 pthread_mutex_unlock(&mainw->avseek_mutex);
2802 }
2803 #endif
2804 }
2805
2806
2807 /**
2808 @brief resync audio playback to the current video frame
2809
2810 if we are using a realtime audio player, resync to frameno
2811 and return TRUE
2812
2813 otherwise return FALSE
2814
2815 this is called internally - for example when the play position jumps, either due
2816 to external transport changes, (e.g. jack transport, osc retrigger / goto)
2817 or if we are looping a video selection, or it may be triggered from the keyboard
2818
2819 this is only active if "audio follows video rate/fps changes" is set
2820 and various other conditions are met.
2821 */
resync_audio(double frameno)2822 boolean resync_audio(double frameno) {
2823 if (!(prefs->audio_opts & AUDIO_OPTS_FOLLOW_FPS)) return FALSE;
2824 // if recording external audio, we are intrinsically in sync
2825 if (mainw->record && prefs->audio_src == AUDIO_SRC_EXT) return TRUE;
2826
2827 // if we are playing an audio generator or an event_list, then resync is meaningless
2828 if ((mainw->event_list && !mainw->multitrack && !mainw->record && !mainw->record_paused)
2829 || mainw->agen_key != 0 || mainw->agen_needs_reinit) return FALSE;
2830
2831 // also can't resync if the playing file has no audio, or prefs dont allow it
2832 if (cfile->achans == 0
2833 || (0
2834 #ifdef HAVE_PULSE_AUDIO
2835 || (prefs->audio_player == AUD_PLAYER_PULSE && mainw->pulsed
2836 && mainw->current_file != mainw->pulsed->playing_file)
2837 #endif
2838 ||
2839 #ifdef ENABLE_JACK
2840 (prefs->audio_player == AUD_PLAYER_JACK && mainw->jackd
2841 && mainw->current_file != mainw->jackd->playing_file) ||
2842 #endif
2843 0))
2844 return FALSE;
2845
2846 #ifdef ENABLE_JACK
2847 if (prefs->audio_player == AUD_PLAYER_JACK && mainw->jackd) {
2848 if (!jack_audio_seek_frame(mainw->jackd, frameno)) {
2849 if (jack_try_reconnect()) jack_audio_seek_frame(mainw->jackd, frameno);
2850 else mainw->video_seek_ready = mainw->audio_seek_ready = TRUE;
2851 }
2852 mainw->startticks = mainw->currticks = lives_get_current_playback_ticks(mainw->origsecs, mainw->orignsecs, NULL);
2853
2854 if (mainw->agen_key == 0 && !mainw->agen_needs_reinit && prefs->audio_src == AUDIO_SRC_INT) {
2855 jack_get_rec_avals(mainw->jackd);
2856 }
2857 return TRUE;
2858 }
2859 #endif
2860
2861 #ifdef HAVE_PULSE_AUDIO
2862 if (prefs->audio_player == AUD_PLAYER_PULSE && mainw->pulsed) {
2863 /* if (mainw->files[mainw->pulsed->playing_file]->pb_fps != 0.) */
2864 /* frameno += (double)(mainw->startticks - mainw->currticks) / TICKS_PER_SECOND_DBL */
2865 /* / mainw->files[mainw->pulsed->playing_file]->pb_fps; */
2866 if (!pulse_audio_seek_frame(mainw->pulsed, frameno)) {
2867 if (pulse_try_reconnect()) pulse_audio_seek_frame(mainw->pulsed, frameno);
2868 else mainw->video_seek_ready = mainw->audio_seek_ready = TRUE;
2869 }
2870 mainw->startticks = mainw->currticks = lives_get_current_playback_ticks(mainw->origsecs, mainw->orignsecs, NULL);
2871
2872 if (mainw->agen_key == 0 && !mainw->agen_needs_reinit && prefs->audio_src == AUDIO_SRC_INT) {
2873 pulse_get_rec_avals(mainw->pulsed);
2874 }
2875 return TRUE;
2876 }
2877 #endif
2878 return FALSE;
2879 }
2880
2881
2882 //////////////////////////////////////////////////////////////////////////
2883 static lives_audio_buf_t *cache_buffer = NULL;
2884 static pthread_t athread;
2885
2886 static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
2887 static pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER;
2888
2889
2890 /**
2891 @brief audio caching worker thread function
2892
2893 run as a thread (from audio_cache_init())
2894
2895 read audio from file into cache
2896 must be done in real time since other threads may be waiting on the cache
2897
2898 during free playback, this is only used by jack (thus far it has proven too complex to implement for pulse, since it uses
2899 variable sized buffers.
2900
2901 This function is also used to cache audio when playing from an event_list. Effects may be applied and the mixer volumes
2902 adjusted.
2903 */
cache_my_audio(void * arg)2904 static void *cache_my_audio(void *arg) {
2905 lives_audio_buf_t *cbuffer = (lives_audio_buf_t *)arg;
2906 char *filename;
2907 int i;
2908
2909 while (!cbuffer->die) {
2910 // wait for request from client (setting cbuffer->is_ready or cbuffer->die)
2911 while (cbuffer->is_ready && !cbuffer->die && mainw->abufs_to_fill <= 0) {
2912 pthread_mutex_lock(&cond_mutex);
2913 pthread_cond_wait(&cond, &cond_mutex);
2914 pthread_mutex_unlock(&cond_mutex);
2915 }
2916
2917 if (cbuffer->die) {
2918 if (!mainw->event_list || (mainw->record
2919 || (mainw->is_rendering && mainw->preview && !mainw->preview_rendering))) {
2920 if (cbuffer->_fd != -1)
2921 lives_close_buffered(cbuffer->_fd);
2922 }
2923 return cbuffer;
2924 }
2925
2926 // read from file and process data
2927 //lives_printerr("got buffer request !\n");
2928
2929 //// for multitrack:
2930
2931 #ifdef ENABLE_JACK
2932 if (prefs->audio_player == AUD_PLAYER_JACK && mainw->jackd && mainw->abufs_to_fill > 0) {
2933 mainw->jackd->abufs[mainw->write_abuf]->samples_filled = 0;
2934 fill_abuffer_from(mainw->jackd->abufs[mainw->write_abuf], mainw->event_list, NULL, FALSE);
2935 continue;
2936 }
2937 #endif
2938 #ifdef HAVE_PULSE_AUDIO
2939 if (prefs->audio_player == AUD_PLAYER_PULSE && mainw->pulsed && mainw->abufs_to_fill > 0) {
2940 mainw->pulsed->abufs[mainw->write_abuf]->samples_filled = 0;
2941 fill_abuffer_from(mainw->pulsed->abufs[mainw->write_abuf], mainw->event_list, NULL, FALSE);
2942 continue;
2943 }
2944 #endif
2945
2946 if (cbuffer->operation != LIVES_READ_OPERATION) {
2947 cbuffer->is_ready = TRUE;
2948 continue;
2949 }
2950
2951 //// for jack audio, free playback
2952
2953 cbuffer->eof = FALSE;
2954
2955 // TODO - if out_asamps changed, we need to free all buffers and set _cachans==0
2956 if (cbuffer->out_asamps != cbuffer->_casamps) {
2957 if (cbuffer->bufferf) {
2958 // free float channels
2959 for (i = 0; i < (cbuffer->_cout_interleaf ? 1 : cbuffer->_cachans); i++) {
2960 lives_free(cbuffer->bufferf[i]);
2961 }
2962 lives_free(cbuffer->bufferf);
2963 cbuffer->bufferf = NULL;
2964 }
2965
2966 if (cbuffer->buffer16) {
2967 // free 16bit channels
2968 for (i = 0; i < (cbuffer->_cout_interleaf ? 1 : cbuffer->_cachans); i++) {
2969 lives_free(cbuffer->buffer16[i]);
2970 }
2971 lives_free(cbuffer->buffer16);
2972 cbuffer->buffer16 = NULL;
2973 }
2974
2975 cbuffer->_cachans = 0;
2976 cbuffer->_cout_interleaf = FALSE;
2977 cbuffer->_csamp_space = 0;
2978 }
2979
2980 // do we need to allocate output buffers ?
2981 switch (cbuffer->out_asamps) {
2982 case 8:
2983 case 24:
2984 case 32:
2985 // not yet implemented
2986 break;
2987 case 16:
2988 // we need 16 bit buffer(s) only
2989 if (cbuffer->bufferf) {
2990 // free float channels
2991 for (i = 0; i < (cbuffer->_cout_interleaf ? 1 : cbuffer->_cachans); i++) {
2992 lives_free(cbuffer->bufferf[i]);
2993 }
2994 lives_free(cbuffer->bufferf);
2995 cbuffer->bufferf = NULL;
2996 }
2997
2998 if ((cbuffer->out_interleaf ? 1 : cbuffer->out_achans) != (cbuffer->_cout_interleaf ? 1 : cbuffer->_cachans)
2999 || (cbuffer->samp_space / (cbuffer->out_interleaf ? 1 : cbuffer->out_achans) !=
3000 (cbuffer->_csamp_space / (cbuffer->_cout_interleaf ? 1 : cbuffer->_cachans)))) {
3001 // channels or samp_space changed
3002
3003 if ((cbuffer->out_interleaf ? 1 : cbuffer->out_achans) > (cbuffer->_cout_interleaf ? 1 : cbuffer->_cachans)) {
3004 // ouput channels increased
3005 cbuffer->buffer16 = (short **)
3006 lives_realloc(cbuffer->buffer16,
3007 (cbuffer->out_interleaf ? 1 : cbuffer->out_achans) * sizeof(short *));
3008 for (i = (cbuffer->_cout_interleaf ? 1 : cbuffer->_cachans);
3009 i < (cbuffer->out_interleaf ? 1 : cbuffer->out_achans); i++) {
3010 cbuffer->buffer16[i] = NULL;
3011 }
3012 }
3013
3014 for (i = 0; i < (cbuffer->out_interleaf ? 1 : cbuffer->out_achans); i++) {
3015 // realloc existing channels and add new ones
3016 cbuffer->buffer16[i] = (short *)lives_realloc(cbuffer->buffer16[i], cbuffer->samp_space * sizeof(short) *
3017 (cbuffer->out_interleaf ? cbuffer->out_achans : 1) + EXTRA_BYTES);
3018 }
3019
3020 // free any excess channels
3021
3022 for (i = (cbuffer->out_interleaf ? 1 : cbuffer->out_achans);
3023 i < (cbuffer->_cout_interleaf ? 1 : cbuffer->_cachans); i++) {
3024 lives_free(cbuffer->buffer16[i]);
3025 }
3026
3027 if ((cbuffer->out_interleaf ? 1 : cbuffer->out_achans) < (cbuffer->_cout_interleaf ? 1 : cbuffer->_cachans)) {
3028 // output channels decreased
3029 cbuffer->buffer16 = (short **)
3030 lives_realloc(cbuffer->buffer16,
3031 (cbuffer->out_interleaf ? 1 : cbuffer->out_achans) * sizeof(short *));
3032 }
3033 }
3034
3035 break;
3036 case -32:
3037 // we need 16 bit buffer(s) and float buffer(s)
3038
3039 // 16 bit buffers follow in out_achans but in_interleaf
3040
3041 if ((cbuffer->in_interleaf ? 1 : cbuffer->out_achans) != (cbuffer->_cin_interleaf ? 1 : cbuffer->_cachans)
3042 || (cbuffer->samp_space / (cbuffer->in_interleaf ? 1 : cbuffer->out_achans) !=
3043 (cbuffer->_csamp_space / (cbuffer->_cin_interleaf ? 1 : cbuffer->_cachans)))) {
3044 // channels or samp_space changed
3045
3046 if ((cbuffer->in_interleaf ? 1 : cbuffer->out_achans) > (cbuffer->_cin_interleaf ? 1 : cbuffer->_cachans)) {
3047 // ouput channels increased
3048 cbuffer->buffer16 = (short **)
3049 lives_realloc(cbuffer->buffer16,
3050 (cbuffer->in_interleaf ? 1 : cbuffer->out_achans) * sizeof(short *));
3051 for (i = (cbuffer->_cin_interleaf ? 1 : cbuffer->_cachans);
3052 i < (cbuffer->in_interleaf ? 1 : cbuffer->out_achans); i++) {
3053 cbuffer->buffer16[i] = NULL;
3054 }
3055 }
3056
3057 for (i = 0; i < (cbuffer->in_interleaf ? 1 : cbuffer->out_achans); i++) {
3058 // realloc existing channels and add new ones
3059 cbuffer->buffer16[i] = (short *)lives_realloc(cbuffer->buffer16[i], cbuffer->samp_space * sizeof(short) *
3060 (cbuffer->in_interleaf ? cbuffer->out_achans : 1) + EXTRA_BYTES);
3061 }
3062
3063 // free any excess channels
3064
3065 for (i = (cbuffer->in_interleaf ? 1 : cbuffer->out_achans); i < (cbuffer->_cin_interleaf ? 1 : cbuffer->_cachans); i++) {
3066 lives_free(cbuffer->buffer16[i]);
3067 }
3068
3069 if ((cbuffer->in_interleaf ? 1 : cbuffer->out_achans) < (cbuffer->_cin_interleaf ? 1 : cbuffer->_cachans)) {
3070 // output channels decreased
3071 cbuffer->buffer16 = (short **)
3072 lives_realloc(cbuffer->buffer16,
3073 (cbuffer->in_interleaf ? 1 : cbuffer->out_achans) * sizeof(short *));
3074 }
3075 }
3076
3077 if ((cbuffer->out_interleaf ? 1 : cbuffer->out_achans) != (cbuffer->_cout_interleaf ? 1 : cbuffer->_cachans)
3078 || (cbuffer->samp_space / (cbuffer->out_interleaf ? 1 : cbuffer->out_achans) !=
3079 (cbuffer->_csamp_space / (cbuffer->_cout_interleaf ? 1 : cbuffer->_cachans)))) {
3080 // channels or samp_space changed
3081
3082 if ((cbuffer->out_interleaf ? 1 : cbuffer->out_achans) > (cbuffer->_cout_interleaf ? 1 : cbuffer->_cachans)) {
3083 // ouput channels increased
3084 cbuffer->bufferf = (float **)
3085 lives_realloc(cbuffer->bufferf,
3086 (cbuffer->out_interleaf ? 1 : cbuffer->out_achans) * sizeof(float *));
3087 for (i = (cbuffer->_cout_interleaf ? 1 : cbuffer->_cachans);
3088 i < (cbuffer->out_interleaf ? 1 : cbuffer->out_achans); i++) {
3089 cbuffer->bufferf[i] = NULL;
3090 }
3091 }
3092
3093 for (i = 0; i < (cbuffer->out_interleaf ? 1 : cbuffer->out_achans); i++) {
3094 // realloc existing channels and add new ones
3095 cbuffer->bufferf[i] = (float *)lives_realloc(cbuffer->bufferf[i], cbuffer->samp_space * sizeof(float) *
3096 (cbuffer->out_interleaf ? cbuffer->out_achans : 1) + EXTRA_BYTES);
3097 }
3098
3099 // free any excess channels
3100
3101 for (i = (cbuffer->out_interleaf ? 1 : cbuffer->out_achans);
3102 i < (cbuffer->_cout_interleaf ? 1 : cbuffer->_cachans); i++) {
3103 lives_free(cbuffer->bufferf[i]);
3104 }
3105
3106 if ((cbuffer->out_interleaf ? 1 : cbuffer->out_achans) > (cbuffer->_cout_interleaf ? 1 : cbuffer->_cachans)) {
3107 // output channels decreased
3108 cbuffer->bufferf = (float **)
3109 lives_realloc(cbuffer->bufferf,
3110 (cbuffer->out_interleaf ? 1 : cbuffer->out_achans) * sizeof(float *));
3111 }
3112 }
3113
3114 break;
3115 default:
3116 break;
3117 }
3118
3119 // update _cinterleaf, etc.
3120 cbuffer->_cin_interleaf = cbuffer->in_interleaf;
3121 cbuffer->_cout_interleaf = cbuffer->out_interleaf;
3122 cbuffer->_csamp_space = cbuffer->samp_space;
3123 cbuffer->_cachans = cbuffer->out_achans;
3124 cbuffer->_casamps = cbuffer->out_asamps;
3125
3126 // open new file if necessary
3127
3128 if (cbuffer->fileno != cbuffer->_cfileno) {
3129 lives_clip_t *afile = mainw->files[cbuffer->fileno];
3130
3131 if (cbuffer->_fd != -1) lives_close_buffered(cbuffer->_fd);
3132
3133 filename = get_audio_file_name(cbuffer->fileno, afile->opening);
3134
3135 cbuffer->_fd = lives_open_buffered_rdonly(filename);
3136 if (cbuffer->_fd == -1) {
3137 lives_printerr("audio cache thread: error opening %s\n", filename);
3138 cbuffer->in_achans = 0;
3139 cbuffer->fileno = -1; ///< let client handle this
3140 cbuffer->is_ready = TRUE;
3141 continue;
3142 }
3143
3144 lives_free(filename);
3145 }
3146
3147 if (cbuffer->fileno != cbuffer->_cfileno || cbuffer->seek != cbuffer->_cseek ||
3148 cbuffer->shrink_factor != cbuffer->_shrink_factor) {
3149 if (cbuffer->sequential || cbuffer->shrink_factor > 0.) {
3150 lives_buffered_rdonly_set_reversed(cbuffer->_fd, FALSE);
3151 } else {
3152 lives_buffered_rdonly_set_reversed(cbuffer->_fd, TRUE);
3153 }
3154 if (cbuffer->fileno != cbuffer->_cfileno || cbuffer->seek != cbuffer->_cseek) {
3155 lives_lseek_buffered_rdonly_absolute(cbuffer->_fd, cbuffer->seek);
3156 }
3157 }
3158
3159 cbuffer->_cfileno = cbuffer->fileno;
3160 cbuffer->_shrink_factor = cbuffer->shrink_factor;
3161
3162 // prepare file read buffer
3163
3164 if (cbuffer->bytesize != cbuffer->_cbytesize) {
3165 cbuffer->_filebuffer = (uint8_t *)lives_realloc(cbuffer->_filebuffer, cbuffer->bytesize);
3166
3167 if (!cbuffer->_filebuffer) {
3168 cbuffer->_cbytesize = cbuffer->bytesize = 0;
3169 cbuffer->in_achans = 0;
3170 cbuffer->is_ready = TRUE;
3171 continue;
3172 }
3173 }
3174
3175 // read from file
3176 cbuffer->_cbytesize = lives_read_buffered(cbuffer->_fd, cbuffer->_filebuffer, cbuffer->bytesize, TRUE);
3177
3178 if (cbuffer->_cbytesize <= 0) {
3179 // there is not much we can do if we get a read error, since we are running in a realtime thread here
3180 // just mark it as 0 channels, 0 bytes
3181 cbuffer->bytesize = cbuffer->_cbytesize = 0;
3182 cbuffer->in_achans = 0;
3183 cbuffer->is_ready = TRUE;
3184 continue;
3185 }
3186
3187 if (cbuffer->_cbytesize < cbuffer->bytesize) {
3188 cbuffer->eof = TRUE;
3189 cbuffer->_csamp_space = (int64_t)((double)cbuffer->samp_space / (double)cbuffer->bytesize * (double)cbuffer->_cbytesize);
3190 cbuffer->samp_space = cbuffer->_csamp_space;
3191 }
3192
3193 cbuffer->bytesize = cbuffer->_cbytesize;
3194 cbuffer->_cseek = (cbuffer->seek += cbuffer->bytesize);
3195
3196 // do conversion
3197
3198 // convert from 8 bit to 16 bit and mono to stereo if necessary
3199 // resample as we go
3200 if (cbuffer->in_asamps == 8) {
3201 // TODO - error on non-interleaved
3202 if (cbuffer->shrink_factor < 0.) {
3203 if (reverse_buffer(cbuffer->_filebuffer, cbuffer->bytesize, cbuffer->in_achans))
3204 cbuffer->shrink_factor = -cbuffer->shrink_factor;
3205 }
3206 sample_move_d8_d16(cbuffer->buffer16[0], (uint8_t *)cbuffer->_filebuffer, cbuffer->samp_space, cbuffer->bytesize,
3207 cbuffer->shrink_factor, cbuffer->out_achans, cbuffer->in_achans, 0);
3208 }
3209 // 16 bit input samples
3210 // resample as we go
3211 else {
3212 if (cbuffer->shrink_factor < 0.) {
3213 if (reverse_buffer(cbuffer->_filebuffer, cbuffer->bytesize, cbuffer->in_achans * 2))
3214 cbuffer->shrink_factor = -cbuffer->shrink_factor;
3215 }
3216 sample_move_d16_d16(cbuffer->buffer16[0], (short *)cbuffer->_filebuffer, cbuffer->samp_space, cbuffer->bytesize,
3217 cbuffer->shrink_factor, cbuffer->out_achans, cbuffer->in_achans,
3218 cbuffer->swap_endian ? SWAP_X_TO_L : 0, 0);
3219 }
3220 cbuffer->shrink_factor = cbuffer->_shrink_factor;
3221
3222 // if our out_asamps is 16, we are done
3223
3224 cbuffer->is_ready = TRUE;
3225 }
3226 return cbuffer;
3227 }
3228
3229
wake_audio_thread(void)3230 void wake_audio_thread(void) {
3231 if (cache_buffer) cache_buffer->is_ready = FALSE;
3232 pthread_mutex_lock(&cond_mutex);
3233 pthread_cond_signal(&cond);
3234 pthread_mutex_unlock(&cond_mutex);
3235 }
3236
3237
audio_cache_init(void)3238 lives_audio_buf_t *audio_cache_init(void) {
3239 cache_buffer = (lives_audio_buf_t *)lives_calloc(1, sizeof(lives_audio_buf_t));
3240 cache_buffer->is_ready = FALSE;
3241 cache_buffer->die = FALSE;
3242
3243 if (!mainw->multitrack) {
3244 cache_buffer->in_achans = 0;
3245
3246 // NULLify all pointers of cache_buffer
3247
3248 cache_buffer->buffer8 = NULL;
3249 cache_buffer->buffer16 = NULL;
3250 cache_buffer->buffer24 = NULL;
3251 cache_buffer->buffer32 = NULL;
3252 cache_buffer->bufferf = NULL;
3253 cache_buffer->_filebuffer = NULL;
3254 cache_buffer->_cbytesize = 0;
3255 cache_buffer->_csamp_space = 0;
3256 cache_buffer->_cachans = 0;
3257 cache_buffer->_casamps = 0;
3258 cache_buffer->_cout_interleaf = FALSE;
3259 cache_buffer->_cin_interleaf = FALSE;
3260 cache_buffer->eof = FALSE;
3261 cache_buffer->sequential = FALSE;
3262
3263 cache_buffer->_cfileno = -1;
3264 cache_buffer->_cseek = -1;
3265 cache_buffer->_fd = -1;
3266 cache_buffer->_shrink_factor = 0.;
3267 }
3268
3269 // init the audio caching thread for rt playback
3270 pthread_create(&athread, NULL, cache_my_audio, cache_buffer);
3271
3272 return cache_buffer;
3273 }
3274
3275
audio_cache_end(void)3276 void audio_cache_end(void) {
3277 lives_audio_buf_t *xcache_buffer;
3278 int i;
3279
3280 pthread_mutex_lock(&mainw->cache_buffer_mutex);
3281 if (!cache_buffer) {
3282 pthread_mutex_unlock(&mainw->cache_buffer_mutex);
3283 return;
3284 }
3285 cache_buffer->die = TRUE; ///< tell cache thread to exit when possible
3286 wake_audio_thread();
3287 pthread_join(athread, NULL);
3288 pthread_mutex_unlock(&mainw->cache_buffer_mutex);
3289
3290 if (!mainw->event_list) {
3291 // free all buffers
3292
3293 for (i = 0; i < (cache_buffer->_cin_interleaf ? 1 : cache_buffer->_cachans); i++) {
3294 if (cache_buffer->buffer8 && cache_buffer->buffer8[i]) lives_free(cache_buffer->buffer8[i]);
3295 if (cache_buffer->buffer16 && cache_buffer->buffer16[i]) lives_free(cache_buffer->buffer16[i]);
3296 if (cache_buffer->buffer24 && cache_buffer->buffer24[i]) lives_free(cache_buffer->buffer24[i]);
3297 if (cache_buffer->buffer32 && cache_buffer->buffer32[i]) lives_free(cache_buffer->buffer32[i]);
3298 if (cache_buffer->bufferf && cache_buffer->bufferf[i]) lives_free(cache_buffer->bufferf[i]);
3299 }
3300
3301 if (cache_buffer->buffer8) lives_free(cache_buffer->buffer8);
3302 if (cache_buffer->buffer16) lives_free(cache_buffer->buffer16);
3303 if (cache_buffer->buffer24) lives_free(cache_buffer->buffer24);
3304 if (cache_buffer->buffer32) lives_free(cache_buffer->buffer32);
3305 if (cache_buffer->bufferf) lives_free(cache_buffer->bufferf);
3306
3307 if (cache_buffer->_filebuffer) lives_free(cache_buffer->_filebuffer);
3308 }
3309
3310 if (cache_buffer->_fd != -1) lives_close_buffered(cache_buffer->_fd);
3311
3312 // make this threadsafe (kind of)
3313 xcache_buffer = cache_buffer;
3314 cache_buffer = NULL;
3315 lives_free(xcache_buffer);
3316
3317 #ifdef ENABLE_JACK
3318 if (prefs->audio_player == AUD_PLAYER_JACK) {
3319 jack_pb_end();
3320 }
3321 #endif
3322 }
3323
audio_cache_get_buffer(void)3324 LIVES_GLOBAL_INLINE lives_audio_buf_t *audio_cache_get_buffer(void) {
3325 return cache_buffer;
3326 }
3327
3328 ///////////////////////////////////////
3329
3330 // plugin handling
3331
get_audio_from_plugin(float ** fbuffer,int nchans,int arate,int nsamps,boolean is_audio_thread)3332 boolean get_audio_from_plugin(float **fbuffer, int nchans, int arate, int nsamps, boolean is_audio_thread) {
3333 // get audio from an audio generator; fbuffer is filled with non-interleaved float
3334 weed_plant_t *inst = rte_keymode_get_instance(mainw->agen_key, rte_key_getmode(mainw->agen_key));
3335 weed_plant_t *orig_inst = inst;
3336 weed_plant_t *filter;
3337 weed_plant_t *channel;
3338 weed_plant_t *ctmpl;
3339 weed_timecode_t tc;
3340 weed_error_t retval;
3341 int flags, cflags;
3342 int xnchans = 0, xxnchans, xrate = 0;
3343 boolean rvary = FALSE, lvary = FALSE;
3344
3345 if (mainw->agen_needs_reinit) {
3346 weed_instance_unref(inst);
3347 return FALSE; // wait for other thread to reinit us
3348 }
3349 tc = (double)mainw->agen_samps_count / (double)arate * TICKS_PER_SECOND_DBL;
3350 filter = weed_instance_get_filter(inst, FALSE);
3351 flags = weed_filter_get_flags(filter);
3352
3353 if (flags & WEED_FILTER_AUDIO_RATES_MAY_VARY) rvary = TRUE;
3354 if (flags & WEED_FILTER_CHANNEL_LAYOUTS_MAY_VARY) lvary = TRUE;
3355
3356 getaud1:
3357
3358 channel = get_enabled_channel(inst, 0, FALSE);
3359 if (channel) {
3360 xnchans = nchans; // preferred value
3361 ctmpl = weed_channel_get_template(channel);
3362 cflags = weed_chantmpl_get_flags(ctmpl);
3363
3364 if (lvary && weed_plant_has_leaf(ctmpl, WEED_LEAF_AUDIO_CHANNELS))
3365 xnchans = weed_get_int_value(ctmpl, WEED_LEAF_AUDIO_CHANNELS, NULL);
3366 else if (weed_plant_has_leaf(filter, WEED_LEAF_MAX_AUDIO_CHANNELS)) {
3367 xxnchans = weed_get_int_value(filter, WEED_LEAF_MAX_AUDIO_CHANNELS, NULL);
3368 if (xxnchans > 0 && xxnchans < nchans) xnchans = xxnchans;
3369 }
3370 if (xnchans > nchans) {
3371 weed_instance_unref(orig_inst);
3372 return FALSE;
3373 }
3374 if (weed_get_int_value(channel, WEED_LEAF_AUDIO_CHANNELS, NULL) != nchans
3375 && (cflags & WEED_CHANNEL_REINIT_ON_LAYOUT_CHANGE))
3376 mainw->agen_needs_reinit = TRUE;
3377 else weed_set_int_value(channel, WEED_LEAF_AUDIO_CHANNELS, nchans);
3378
3379 xrate = arate;
3380 if (rvary && weed_plant_has_leaf(ctmpl, WEED_LEAF_AUDIO_RATE))
3381 xrate = weed_get_int_value(ctmpl, WEED_LEAF_AUDIO_RATE, NULL);
3382 else if (weed_plant_has_leaf(filter, WEED_LEAF_AUDIO_RATE))
3383 xrate = weed_get_int_value(filter, WEED_LEAF_AUDIO_RATE, NULL);
3384 if (arate != xrate) {
3385 weed_instance_unref(orig_inst);
3386 return FALSE;
3387 }
3388
3389 if (weed_get_int_value(channel, WEED_LEAF_AUDIO_RATE, NULL) != arate) {
3390 if (cflags & WEED_CHANNEL_REINIT_ON_RATE_CHANGE) {
3391 mainw->agen_needs_reinit = TRUE;
3392 }
3393 }
3394
3395 weed_set_int_value(channel, WEED_LEAF_AUDIO_RATE, arate);
3396
3397 if (mainw->agen_needs_reinit) {
3398 // allow main thread to complete the reinit so we do not delay; just return silence
3399 weed_instance_unref(orig_inst);
3400 return FALSE;
3401 }
3402
3403 weed_set_int64_value(channel, WEED_LEAF_TIMECODE, tc);
3404
3405 weed_channel_set_audio_data(channel, fbuffer, arate, xnchans, nsamps);
3406 weed_set_double_value(inst, WEED_LEAF_FPS, cfile->pb_fps);
3407 }
3408
3409 if (mainw->pconx && !(mainw->preview || mainw->is_rendering)) {
3410 // chain any data pipelines
3411 if (!pthread_mutex_trylock(&mainw->fx_mutex[mainw->agen_key - 1])) {
3412 mainw->agen_needs_reinit = pconx_chain_data(mainw->agen_key - 1, rte_key_getmode(mainw->agen_key), is_audio_thread);
3413 filter_mutex_unlock(mainw->agen_key - 1);
3414
3415 if (mainw->agen_needs_reinit) {
3416 // allow main thread to complete the reinit so we do not delay; just return silence
3417 weed_instance_unref(orig_inst);
3418 return FALSE;
3419 }
3420 }
3421 }
3422
3423 retval = run_process_func(inst, tc, mainw->agen_key);
3424
3425 if (retval != WEED_SUCCESS) {
3426 if (retval == WEED_ERROR_REINIT_NEEDED) mainw->agen_needs_reinit = TRUE;
3427 weed_instance_unref(orig_inst);
3428 return FALSE;
3429 }
3430
3431 if (channel && xnchans == 1 && nchans == 2) {
3432 // if we got mono but we wanted stereo, copy to right channel
3433 lives_memcpy(fbuffer[1], fbuffer[0], nsamps * sizeof(float));
3434 }
3435
3436 if (weed_plant_has_leaf(inst, WEED_LEAF_HOST_NEXT_INSTANCE)) {
3437 // handle compound fx
3438 inst = weed_get_plantptr_value(inst, WEED_LEAF_HOST_NEXT_INSTANCE, NULL);
3439 goto getaud1;
3440 }
3441
3442 mainw->agen_samps_count += nsamps;
3443
3444 weed_instance_unref(orig_inst);
3445 return TRUE;
3446 }
3447
3448
reinit_audio_gen(void)3449 void reinit_audio_gen(void) {
3450 int agen_key = mainw->agen_key;
3451 int ret;
3452
3453 weed_plant_t *inst = rte_keymode_get_instance(agen_key, rte_key_getmode(mainw->agen_key));
3454
3455 ret = weed_reinit_effect(inst, TRUE);
3456 if (ret == FILTER_SUCCESS || ret == FILTER_INFO_REINITED) {
3457 mainw->agen_needs_reinit = FALSE;
3458 mainw->agen_key = agen_key;
3459 }
3460 weed_instance_unref(inst);
3461 }
3462
3463
3464 ////////////////////////////////////////
3465 // apply audio as "rendered effect"
3466
3467 static int audio_fd;
3468 static char *audio_file;
3469
3470 off64_t audio_pos;
3471
3472 weed_timecode_t aud_tc;
3473
apply_rte_audio_init(void)3474 boolean apply_rte_audio_init(void) {
3475 char *com;
3476
3477 if (!prefs->conserve_space) {
3478 com = lives_strdup_printf("%s backup_audio %s", prefs->backend_sync, cfile->handle);
3479 lives_system(com, FALSE);
3480 lives_free(com);
3481
3482 if (THREADVAR(com_failed)) {
3483 d_print_failed();
3484 return FALSE;
3485 }
3486 }
3487
3488 audio_pos = (double)((cfile->start - 1) * cfile->arate * cfile->achans * cfile->asampsize / 8) / cfile->fps;
3489 audio_file = lives_get_audio_file_name(mainw->current_file);
3490
3491 audio_fd = lives_open_buffered_writer(audio_file, DEF_FILE_PERMS, TRUE);
3492
3493 if (audio_fd == -1) return FALSE;
3494
3495 if (audio_pos > cfile->afilesize) {
3496 off64_t audio_end_pos = (double)((cfile->start - 1) * cfile->arate * cfile->achans * cfile->asampsize / 8) / cfile->fps;
3497 pad_with_silence(audio_fd, NULL, audio_pos, audio_end_pos, cfile->asampsize, cfile->signed_endian & AFORM_UNSIGNED,
3498 cfile->signed_endian & AFORM_BIG_ENDIAN);
3499 } else lives_lseek_buffered_writer(audio_fd, audio_pos);
3500
3501 aud_tc = 0;
3502
3503 return TRUE;
3504 }
3505
3506
apply_rte_audio_end(boolean del)3507 void apply_rte_audio_end(boolean del) {
3508 lives_close_buffered(audio_fd);
3509 if (del) lives_rm(audio_file);
3510 lives_free(audio_file);
3511 }
3512
3513
apply_rte_audio(int64_t nframes)3514 boolean apply_rte_audio(int64_t nframes) {
3515 // CALLED When we are rendering audio to a file
3516
3517 // - read nframes from clip or generator
3518 // - convert to float if necessary
3519 // - send to rte audio effects
3520 // - convert back to s16 or s8
3521 // - save to audio_fd
3522 weed_layer_t *layer;
3523 size_t tbytes;
3524 uint8_t *in_buff;
3525 float **fltbuf, *fltbufni = NULL;
3526 short *shortbuf = NULL;
3527 boolean rev_endian = FALSE;
3528
3529 int i;
3530
3531 int abigendian = cfile->signed_endian & AFORM_BIG_ENDIAN;
3532 int onframes;
3533
3534 // read nframes of audio from clip or generator
3535
3536 if ((abigendian && capable->byte_order == LIVES_LITTLE_ENDIAN) || (!abigendian &&
3537 capable->byte_order == LIVES_BIG_ENDIAN)) rev_endian = TRUE;
3538
3539 tbytes = nframes * cfile->achans * cfile->asampsize / 8;
3540
3541 if (mainw->agen_key == 0) {
3542 if (tbytes + audio_pos > cfile->afilesize) tbytes = cfile->afilesize - audio_pos;
3543 if (tbytes <= 0) return TRUE;
3544 nframes = tbytes / cfile->achans / (cfile->asampsize / 8);
3545 }
3546
3547 onframes = nframes;
3548
3549 in_buff = (uint8_t *)lives_calloc_safety(tbytes, 1);
3550 if (!in_buff) return FALSE;
3551
3552 if (cfile->asampsize == 8) {
3553 shortbuf = (short *)lives_calloc_safety(tbytes / sizeof(short), sizeof(short));
3554 if (!shortbuf) {
3555 lives_free(in_buff);
3556 return FALSE;
3557 }
3558 }
3559
3560 fltbuf = (float **)lives_calloc(cfile->achans, sizeof(float *));
3561
3562 if (mainw->agen_key == 0) {
3563 // read from audio_fd
3564
3565 tbytes = lives_read_buffered(audio_fd, in_buff, tbytes, FALSE);
3566
3567 if (THREADVAR(read_failed) == audio_fd + 1) {
3568 THREADVAR(read_failed) = 0;
3569 do_read_failed_error_s(audio_file, NULL);
3570 lives_freep((void **)&THREADVAR(read_failed_file));
3571 lives_free(fltbuf);
3572 lives_free(in_buff);
3573 lives_freep((void **)&shortbuf);
3574 return FALSE;
3575 }
3576
3577 if (cfile->asampsize == 8) {
3578 sample_move_d8_d16(shortbuf, in_buff, nframes, tbytes,
3579 1.0, cfile->achans, cfile->achans, 0);
3580 } else shortbuf = (short *)in_buff;
3581
3582 nframes = tbytes / cfile->achans / (cfile->asampsize / 8);
3583
3584 // convert to float
3585
3586 for (i = 0; i < cfile->achans; i++) {
3587 // convert s16 to non-interleaved float
3588 fltbuf[i] = (float *)lives_calloc(nframes, sizeof(float));
3589 if (!fltbuf[i]) {
3590 for (--i; i >= 0; i--) {
3591 lives_free(fltbuf[i]);
3592 }
3593 lives_free(fltbuf);
3594 if (shortbuf != (short *)in_buff) lives_free(shortbuf);
3595 lives_free(in_buff);
3596 return FALSE;
3597 }
3598 lives_memset(fltbuf[i], 0, nframes * sizeof(float));
3599 if (nframes > 0) sample_move_d16_float(fltbuf[i], shortbuf + i, nframes, cfile->achans, \
3600 (cfile->signed_endian & AFORM_UNSIGNED), rev_endian,
3601 lives_vol_from_linear(cfile->vol));
3602 }
3603 } else {
3604 // read from plugin. This should already be float.
3605 get_audio_from_plugin(fltbuf, cfile->achans, cfile->arate, nframes, FALSE);
3606 }
3607
3608 // apply any audio effects
3609
3610 aud_tc += (double)onframes / (double)cfile->arate * TICKS_PER_SECOND_DBL;
3611 // apply any audio effects with in_channels
3612
3613 layer = weed_layer_new(WEED_LAYER_TYPE_AUDIO);
3614 weed_layer_set_audio_data(layer, fltbuf, cfile->arate, cfile->achans, onframes);
3615 weed_apply_audio_effects_rt(layer, aud_tc, FALSE, FALSE);
3616 lives_free(fltbuf);
3617 fltbuf = weed_layer_get_audio_data(layer, NULL);
3618 weed_layer_set_audio_data(layer, NULL, 0, 0, 0);
3619 weed_layer_free(layer);
3620
3621 if (!(has_audio_filters(AF_TYPE_NONA) || mainw->agen_key != 0)) {
3622 // analysers only - no need to save (just render as normal)
3623 // or, audio is being generated (we rendered it to ascrap file)
3624
3625 audio_pos += tbytes;
3626
3627 if (!fltbufni) {
3628 for (i = 0; i < cfile->achans; i++) {
3629 lives_free(fltbuf[i]);
3630 }
3631 } else lives_free(fltbufni);
3632
3633 lives_free(fltbuf);
3634
3635 if (shortbuf != (short *)in_buff) lives_free(shortbuf);
3636 lives_free(in_buff);
3637
3638 return TRUE;
3639 }
3640
3641 // convert float audio back to int
3642 sample_move_float_int(in_buff, fltbuf, onframes, 1.0, cfile->achans, cfile->asampsize, (cfile->signed_endian & AFORM_UNSIGNED),
3643 !(cfile->signed_endian & AFORM_BIG_ENDIAN), FALSE, 1.0);
3644
3645 if (!fltbufni) {
3646 for (i = 0; i < cfile->achans; i++) {
3647 lives_free(fltbuf[i]);
3648 }
3649 } else lives_free(fltbufni);
3650
3651 lives_free(fltbuf);
3652
3653 if (audio_fd >= 0) {
3654 // save to file
3655 lives_lseek_buffered_writer(audio_fd, audio_pos);
3656 tbytes = onframes * cfile->achans * cfile->asampsize / 8;
3657 lives_write_buffered(audio_fd, (const char *)in_buff, tbytes, FALSE);
3658 audio_pos += tbytes;
3659 }
3660
3661 if (shortbuf != (short *)in_buff) lives_free(shortbuf);
3662 lives_free(in_buff);
3663
3664 if (THREADVAR(write_failed) == audio_fd + 1) {
3665 THREADVAR(write_failed) = 0;
3666 do_write_failed_error_s(audio_file, NULL);
3667 return FALSE;
3668 }
3669
3670 return TRUE;
3671 }
3672
3673
3674 /**
3675 @brief fill the audio channel(s) for effects with mixed audio / video
3676
3677 push audio from abuf into an audio channel
3678 audio will be formatted to the channel requested format
3679
3680 when we have audio effects running, the buffer is constantly fiiled from the audio thread (we have two buffers so that
3681 we dont hang the player during read). When the first client reads, the buffers are swapped.
3682
3683 if player is jack, we will have non-interleaved float, if player is pulse, we will have interleaved S16 so we have to convert to float and
3684 then back again.
3685
3686 (this is currently only used to push audio to generators, since there are currently no filters which allow both video and audio input)
3687 */
push_audio_to_channel(weed_plant_t * filter,weed_plant_t * achan,lives_audio_buf_t * abuf)3688 boolean push_audio_to_channel(weed_plant_t *filter, weed_plant_t *achan, lives_audio_buf_t *abuf) {
3689 float **dst, *src;
3690
3691 weed_plant_t *ctmpl;
3692
3693 double scale;
3694
3695 size_t samps, offs = 0;
3696 boolean rvary = FALSE, lvary = FALSE;
3697 int trate, tchans, xnchans, flags;
3698 size_t alen;
3699
3700 int i;
3701
3702 if (abuf->samples_filled == 0) {
3703 weed_layer_set_audio_data(achan, NULL, 0, 0, 0);
3704 return FALSE;
3705 }
3706
3707 samps = abuf->samples_filled;
3708 //if (abuf->in_interleaf) samps /= abuf->in_achans;
3709
3710 ctmpl = weed_get_plantptr_value(achan, WEED_LEAF_TEMPLATE, NULL);
3711
3712 flags = weed_get_int_value(filter, WEED_LEAF_FLAGS, NULL);
3713 if (flags & WEED_FILTER_AUDIO_RATES_MAY_VARY) rvary = TRUE;
3714 if (flags & WEED_FILTER_CHANNEL_LAYOUTS_MAY_VARY) lvary = TRUE;
3715
3716 if (!has_audio_chans_out(filter, FALSE)) {
3717 int maxlen = weed_chantmpl_get_max_audio_length(ctmpl);
3718 if (maxlen > 0) {
3719 if (abuf->in_interleaf) maxlen *= abuf->in_achans;
3720 if (maxlen < samps) {
3721 offs = samps - maxlen;
3722 samps = maxlen;
3723 }
3724 }
3725 }
3726
3727 // TODO: can be list
3728 if (rvary && weed_plant_has_leaf(ctmpl, WEED_LEAF_AUDIO_RATE))
3729 trate = weed_get_int_value(ctmpl, WEED_LEAF_AUDIO_RATE, NULL);
3730 else if (weed_plant_has_leaf(filter, WEED_LEAF_AUDIO_RATE))
3731 trate = weed_get_int_value(filter, WEED_LEAF_AUDIO_RATE, NULL);
3732 else trate = DEFAULT_AUDIO_RATE;
3733
3734 tchans = DEFAULT_AUDIO_CHANS;
3735 if (lvary && weed_plant_has_leaf(ctmpl, WEED_LEAF_AUDIO_CHANNELS))
3736 tchans = weed_get_int_value(ctmpl, WEED_LEAF_AUDIO_CHANNELS, NULL);
3737 else if (weed_plant_has_leaf(filter, WEED_LEAF_MAX_AUDIO_CHANNELS)) {
3738 xnchans = weed_get_int_value(filter, WEED_LEAF_MAX_AUDIO_CHANNELS, NULL);
3739 if (xnchans > 0 && xnchans < tchans) tchans = xnchans;
3740 }
3741
3742 #ifdef DEBUG_AFB
3743 g_print("push from afb %d\n", abuf->samples_filled);
3744 #endif
3745
3746 // plugin will get float, so we first convert to that
3747 if (!abuf->bufferf) {
3748 // try 8 bit -> 16
3749 if (abuf->buffer8 && !abuf->buffer16) {
3750 int swap = 0;
3751 if (!abuf->s8_signed) swap = SWAP_U_TO_S;
3752 abuf->s16_signed = TRUE;
3753 abuf->buffer16 = (short **)lives_calloc(abuf->out_achans, sizeof(short *));
3754 for (i = 0; i < abuf->out_achans; i++) {
3755 abuf->buffer16[i] = (short *)lives_calloc_safety(samps, sizeof(short));
3756 sample_move_d8_d16(abuf->buffer16[i], &abuf->buffer8[i][offs], samps, samps * sizeof(short),
3757 1.0, abuf->out_achans, abuf->out_achans, swap);
3758
3759 }
3760 }
3761
3762 // try convert S16 -> float
3763 if (abuf->buffer16) {
3764 abuf->bufferf = (float **)lives_calloc(abuf->out_achans, sizeof(float *));
3765 for (i = 0; i < abuf->out_achans; i++) {
3766 if (!abuf->in_interleaf) {
3767 abuf->bufferf[i] = (float *)lives_calloc_safety(abuf->samples_filled, sizeof(float));
3768 sample_move_d16_float(abuf->bufferf[i], &abuf->buffer16[0][offs], samps, 1,
3769 (abuf->s16_signed ? AFORM_SIGNED : AFORM_UNSIGNED),
3770 abuf->swap_endian, lives_vol_from_linear(cfile->vol));
3771 offs += abuf->samples_filled;
3772 } else {
3773 abuf->bufferf[i] = (float *)lives_calloc_safety(samps / abuf->out_achans, sizeof(float));
3774 sample_move_d16_float(abuf->bufferf[i], &abuf->buffer16[0][i], samps / abuf->in_achans, abuf->in_achans,
3775 (abuf->s16_signed ? AFORM_SIGNED : AFORM_UNSIGNED),
3776 abuf->swap_endian, lives_vol_from_linear(cfile->vol));
3777 }
3778 }
3779 abuf->out_interleaf = FALSE;
3780 }
3781 }
3782
3783 if (!abuf->bufferf) return FALSE;
3784 // now we should have float
3785
3786 if (abuf->in_interleaf) samps /= abuf->in_achans;
3787
3788 // push to achan "audio_data", taking into account "audio_data_length" and "audio_channels"
3789
3790 alen = samps;
3791
3792 if (abuf->arate == 0) return FALSE;
3793 scale = (double)trate / (double)abuf->arate;
3794 alen = (size_t)(fabs(((double)alen * scale)));
3795
3796 // malloc audio_data
3797 dst = (float **)lives_calloc(tchans, sizeof(float *));
3798
3799 // copy data from abuf->bufferf[] to "audio_data"
3800 for (i = 0; i < tchans; i++) {
3801 pthread_mutex_lock(&mainw->abuf_mutex);
3802 src = abuf->bufferf[i % abuf->out_achans];
3803 if (src) {
3804 dst[i] = lives_calloc(alen, sizeof(float));
3805 if (abuf->arate == trate) {
3806 lives_memcpy(dst[i], src, alen * sizeof(float));
3807 } else {
3808 // needs resample
3809 sample_move_float_float(dst[i], src, alen, scale, 1);
3810 }
3811 } else dst[i] = NULL;
3812 pthread_mutex_unlock(&mainw->abuf_mutex);
3813 }
3814
3815 // set channel values
3816 weed_channel_set_audio_data(achan, dst, trate, tchans, alen);
3817 lives_free(dst);
3818 return TRUE;
3819 }
3820
3821
3822 ////////////////////////////////////////
3823 // audio streaming, older API
3824
3825 lives_pgid_t astream_pgid = 0;
3826
start_audio_stream(void)3827 boolean start_audio_stream(void) {
3828 const char *playername = "audiostreamer.pl";
3829 char *astream_name = NULL;
3830 char *astream_name_out = NULL;
3831
3832 // playback plugin wants an audio stream - so fork and run the stream
3833 // player
3834 char *astname = lives_strdup_printf("livesaudio-%d.pcm", capable->mainpid);
3835 char *astname_out = lives_strdup_printf("livesaudio-%d.stream", capable->mainpid);
3836 char *astreamer, *com;
3837
3838 int arate = 0;
3839 int afd;
3840 lives_alarm_t alarm_handle;
3841
3842 ticks_t timeout = 0;
3843
3844 astream_name = lives_build_filename(prefs->workdir, astname, NULL);
3845
3846 #ifndef IS_MINGW
3847 mkfifo(astream_name, S_IRUSR | S_IWUSR);
3848 #endif
3849
3850 astream_name_out = lives_build_filename(prefs->workdir, astname_out, NULL);
3851
3852 lives_free(astname);
3853 lives_free(astname_out);
3854
3855 if (prefs->audio_player == AUD_PLAYER_PULSE) {
3856 #ifdef HAVE_PULSE_AUDIO
3857 arate = (int)mainw->pulsed->out_arate;
3858 // TODO - chans, samps, signed, endian
3859 #endif
3860 }
3861
3862 #ifdef ENABLE_JACK
3863 if (prefs->audio_player == AUD_PLAYER_JACK) {
3864 arate = (int)mainw->jackd->sample_out_rate;
3865 // TODO - chans, samps, signed, endian
3866
3867 }
3868 #endif
3869
3870 astreamer = lives_build_filename(prefs->lib_dir, PLUGIN_EXEC_DIR, PLUGIN_AUDIO_STREAM, playername, NULL);
3871 com = lives_strdup_printf("%s play %d \"%s\" \"%s\" %d", astreamer, mainw->vpp->audio_codec, astream_name, astream_name_out,
3872 arate);
3873 lives_free(astreamer);
3874
3875 astream_pgid = lives_fork(com);
3876
3877 alarm_handle = lives_alarm_set(LIVES_DEFAULT_TIMEOUT);
3878
3879 do {
3880 // wait for other thread to create stream (or timeout)
3881 afd = lives_open2(astream_name, O_WRONLY | O_SYNC);
3882 if (afd != -1) break;
3883 lives_usleep(prefs->sleep_time);
3884 } while ((timeout = lives_alarm_check(alarm_handle)) > 0);
3885 lives_alarm_clear(alarm_handle);
3886
3887 if (prefs->audio_player == AUD_PLAYER_PULSE) {
3888 #ifdef HAVE_PULSE_AUDIO
3889 mainw->pulsed->astream_fd = afd;
3890 #endif
3891 }
3892
3893 #ifdef ENABLE_JACK
3894 if (prefs->audio_player == AUD_PLAYER_JACK) {
3895 mainw->jackd->astream_fd = afd;
3896 }
3897 #endif
3898
3899 lives_free(astream_name);
3900 lives_free(astream_name_out);
3901
3902 return TRUE;
3903 }
3904
3905
stop_audio_stream(void)3906 void stop_audio_stream(void) {
3907 if (astream_pgid > 0) {
3908 // if we were streaming audio, kill it
3909 const char *playername = "audiostreamer.pl";
3910 char *astname = lives_strdup_printf("livesaudio-%d.pcm", capable->mainpid);
3911 char *astname_out = lives_strdup_printf("livesaudio-%d.stream", capable->mainpid);
3912 char *astreamer = lives_build_filename(prefs->lib_dir, PLUGIN_EXEC_DIR, PLUGIN_AUDIO_STREAM, playername, NULL);
3913
3914 char *astream_name = lives_build_filename(prefs->workdir, astname, NULL);
3915 char *astream_name_out = lives_build_filename(prefs->workdir, astname_out, NULL);
3916
3917 char *com;
3918
3919 lives_free(astname);
3920 lives_free(astname_out);
3921
3922 #ifdef HAVE_PULSE_AUDIO
3923 if (prefs->audio_player == AUD_PLAYER_PULSE) {
3924 if (mainw->pulsed->astream_fd > -1) close(mainw->pulsed->astream_fd);
3925 mainw->pulsed->astream_fd = -1;
3926 }
3927 #endif
3928 #ifdef ENABLE_JACK
3929 if (prefs->audio_player == AUD_PLAYER_JACK) {
3930 if (mainw->jackd->astream_fd > -1) close(mainw->jackd->astream_fd);
3931 mainw->jackd->astream_fd = -1;
3932 }
3933 #endif
3934
3935 lives_killpg(astream_pgid, LIVES_SIGKILL);
3936 lives_rm(astream_name);
3937 lives_free(astream_name);
3938
3939 // astreamer should remove cooked stream
3940 com = lives_strdup_printf("\"%s\" cleanup %d \"%s\"", astreamer, mainw->vpp->audio_codec, astream_name_out);
3941 lives_system(com, FALSE);
3942 lives_free(astreamer);
3943 lives_free(com);
3944 lives_free(astream_name_out);
3945 }
3946 }
3947
3948
clear_audio_stream(void)3949 void clear_audio_stream(void) {
3950 // remove raw and cooked streams
3951 char *astname = lives_strdup_printf("livesaudio-%d.pcm", capable->mainpid);
3952 char *astream_name = lives_build_filename(prefs->workdir, astname, NULL);
3953 char *astname_out = lives_strdup_printf("livesaudio-%d.stream", capable->mainpid);
3954 char *astream_name_out = lives_build_filename(prefs->workdir, astname_out, NULL);
3955 lives_rm(astream_name);
3956 lives_rm(astream_name_out);
3957 lives_free(astname);
3958 lives_free(astream_name);
3959 lives_free(astname_out);
3960 lives_free(astream_name_out);
3961 }
3962
3963
audio_stream(void * buff,size_t nbytes,int fd)3964 LIVES_GLOBAL_INLINE void audio_stream(void *buff, size_t nbytes, int fd) {
3965 if (fd != -1) {
3966 lives_write(fd, buff, nbytes, TRUE);
3967 }
3968 }
3969
3970
handle_audio_timeout(void)3971 LIVES_GLOBAL_INLINE lives_cancel_t handle_audio_timeout(void) {
3972 char *msg2 = (prefs->audio_player == AUD_PLAYER_PULSE) ? lives_strdup(
3973 _("\nClick Retry to attempt to restart the audio server.\n")) :
3974 lives_strdup("");
3975
3976 char *msg = lives_strdup_printf(
3977 _("LiVES was unable to connect to %s.\nPlease check your audio settings and restart %s\n"
3978 "and LiVES if necessary.\n%s"),
3979 audio_player_get_display_name(prefs->aplayer),
3980 audio_player_get_display_name(prefs->aplayer), msg2);
3981 if (prefs->audio_player == AUD_PLAYER_PULSE) {
3982 #ifdef HAVE_PULSE_AUDIO
3983 int retval = do_abort_cancel_retry_dialog(msg);
3984 if (retval == LIVES_RESPONSE_RETRY) pulse_try_reconnect();
3985 else {
3986 mainw->aplayer_broken = TRUE;
3987 switch_aud_to_none(FALSE);
3988 mainw->video_seek_ready = mainw->audio_seek_ready = TRUE;
3989 }
3990 #endif
3991 } else {
3992 do_error_dialog(msg);
3993 mainw->aplayer_broken = TRUE;
3994 switch_aud_to_none(FALSE);
3995 mainw->video_seek_ready = mainw->audio_seek_ready = TRUE;
3996 }
3997 lives_free(msg);
3998 lives_free(msg2);
3999 return CANCEL_ERROR;
4000 }
4001
4002
4003 #if 0
4004 void nullaudio_time_reset(int64_t offset) {
4005 mainw->nullaudo_startticks = lives_get_current_ticks();
4006 mainw->nullaudio_seek_posn = 0;
4007 mainw->nullaudio_arate = DEF_AUDIO_RATE;
4008 mainw->nullaudio_playing_file = -1;
4009 mainw->deltaticks = mainw->startticks = 0;
4010 }
4011
4012
4013 void nullaudio_arate_set(int arate) {
4014 mainw->nullaudio_arate = arate;
4015 }
4016
4017
4018 void nullaudio_seek_set(offs64_t seek_posn) {
4019 // (virtual) seek posn in bytes
4020 mainw->nullaudio_seek_posn = seek_posn;
4021 }
4022
4023
4024 void nullaudio_clip_set(int clipno) {
4025 mainw->nullaudio_playing_file = clipno;
4026 }
4027
4028
4029 int64_t nullaudio_update_seek_posn() {
4030 if (!CURRENT_CLIP_HAS_AUDIO) return mainw->nullaudio_seek_posn;
4031 else {
4032 ticks_t current_ticks = lives_get_current_ticks();
4033 mainw->nullaudio_seek_posn += ((int64_t)((double)(current_ticks - mainw->nullaudio_start_ticks) / USEC_TO_TICKS / ONE_MILLION. *
4034 mainw->nullaudio_arate)) * afile->achans * (afile->asampsize >> 3);
4035 mainw->nullaudo_startticks = current_ticks;
4036 if (mainw->nullaudio_seek_posn < 0) {
4037 if (mainw->nullaudio_loop == AUDIO_LOOP_NONE) {
4038 if (mainw->whentostop == STOP_ON_AUD_END) {
4039 mainw->cancelled = CANCEL_AUD_END;
4040 }
4041 } else {
4042 if (mainw->nullaudio_loop == AUDIO_LOOP_PINGPONG) {
4043 mainw->nullaudio_arate = -mainw->nullaudio->arate;
4044 mainw->nullaudio_seek_posn = 0;
4045 } else mainw->nullaudio_seek_posn += mainw->nullaudio_seek_end;
4046 }
4047 } else {
4048 if (mainw->nullaudio_seek_posn > mainw->nullaudio_seek_end) {
4049 // reached the end, forwards
4050 if (mainw->nullaudio_loop == AUDIO_LOOP_NONE) {
4051 if (mainw->whentostop == STOP_ON_AUD_END) {
4052 mainw->cancelled = CANCEL_AUD_END;
4053 }
4054 } else {
4055 if (mainw->nullaudio_loop == AUDIO_LOOP_PINGPONG) {
4056 mainw->nullaudio_arate = -mainw->nullaudio_arate;
4057 mainw->nullaudio_seek_posn = mainw->nullaudio_seek_end - (mainw->nullaudio_seek_pos - mainw->nullaudio_seek_end);
4058 } else {
4059 mainw->nullaudio_seek_posn -= mainw->nullaudio_seek_end;
4060 }
4061 nullaudio_set_rec_avals();
4062 // *INDENT-OFF*
4063 }}}}
4064 // *INDENT-ON*
4065 }
4066
4067
4068 void nullaudio_get_rec_avals(void) {
4069 lives_clip_t *afile = mainw->files[mainw->nullaudio_playing_file];
4070 mainw->rec_aclip = mainw->nulllaudio_playing_file;
4071
4072 if (mainw->rec_aclip != -1) {
4073 mainw->rec_aseek = (double)mainw->nullaudio_seek_pos / (double)(afile->arps * afile->achans * afile->asampsize / 8);
4074 mainw->rec_avel = SIGNED_DIVIDE((double)pulsed->in_arate, (double)afile->arate);
4075 }
4076 }
4077
4078
4079 static void nullaudio_set_rec_avals(boolean is_forward) {
4080 // record direction change (internal)
4081 mainw->rec_aclip = mainw->nullaudio_playing_file;
4082 if (mainw->rec_aclip != -1) {
4083 nullaudio_get_rec_avals();
4084 }
4085 }
4086
4087 #endif
4088