LiVES 3.2.0
audio.c
Go to the documentation of this file.
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
14static char *storedfnames[NSTOREDFDS];
15static int storedfds[NSTOREDFDS];
16static boolean storedfdsset = FALSE;
17
18
19static 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
28LIVES_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
38LIVES_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
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
65LIVES_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
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
82void append_to_audio_bufferf(float *src, uint64_t nsamples, int channum) {
83 // append float audio to the audio frame buffer
84 size_t nsampsize;
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
118void 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
155void 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
200
201#ifdef DEBUG_AFB
202 g_print("init afb\n");
203#endif
204}
205
206
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
248float 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];
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) {
269 return xx;
270 }
271 }
272 atime += 1. / afile->arps;
273 }
275 return xx;
276 }
277}
278
279
280boolean 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;
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;
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) {
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));
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;
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 }
365 }
366 if (mainw->cancelled != CANCEL_NONE || THREADVAR(read_failed) || THREADVAR(write_failed)) {
367 return FALSE;
368 }
369 return TRUE;
370 }
371}
372
373
374float 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;
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
415LIVES_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
421void 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);
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
459void 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
524void 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)
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
617void 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
677float 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
745void 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
793int64_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
888int64_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
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++;
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
993int64_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
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++;
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
1094
1095static 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
1107boolean 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
1125boolean 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
1145static 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
1159boolean 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
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
1247 }
1248}
1249
1250
1275//#define DEBUG_ARENDER
1276int64_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;
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
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 {
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
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
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 }
1557 zavel = avels[track] * (double)in_arate[track] / (double)out_arate;
1558
1559 //g_print("zavel is %f\n", zavel);
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.) {
1578 lives_lseek_buffered_rdonly(in_fd[track], - tbytes);
1579 } else {
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
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);
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++) {
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;
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) {
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
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
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 *));
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
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) {
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]) {
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);
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) {
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 {
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
1813void 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
1835void preview_audio(void) {
1836 // start a minimalistic player with only audio
1837 mainw->play_start = cfile->start;
1838 mainw->play_end = cfile->end;
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
1854 if (mainw->jackd) jack_aud_pb_ready(mainw->current_file);
1855 }
1856#endif
1857#ifdef HAVE_PULSE_AUDIO
1859 if (mainw->pulsed) pulse_aud_pb_ready(mainw->current_file);
1860 }
1861#endif
1862#ifdef ENABLE_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
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);
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)) {
1893 return;
1894 }
1895 }
1896#endif
1897
1898 while (mainw->cancelled == CANCEL_NONE) {
1900 lives_nanosleep(1000);
1901 }
1902 mainw->playing_file = -1;
1903
1904 // reset audio buffers
1905#ifdef ENABLE_JACK
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
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
1925 lives_ce_update_timeline(0, cfile->real_pointer_time);
1928 }
1929
1930#ifdef ENABLE_JACK
1932 // tell jack client to close audio file
1933 if (mainw->jackd && mainw->jackd->playing_file > 0) {
1934 ticks_t timeout = 0;
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 }
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
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;
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 }
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) {
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
1992 float ovol = cfile->vol;
1993 cfile->vol = (float)mainw->fx1_val;
1994 preview_audio();
1995 cfile->vol = ovol;
1997 mainw->error = FALSE;
1998}
1999
2000
2001boolean 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
2018void 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);
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;
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;
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
2135 // show countdown/stop dialog
2137 d_print(_("Recording audio..."));
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 }
2151 jack_rec_audio_end(!prefs->perm_audio_reader, TRUE);
2152}
2153
2154
2155void 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
2183void 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) {
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;
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
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
2297 // show countdown/stop dialog
2299 d_print(_("Recording audio..."));
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 }
2313 pulse_rec_audio_end(!prefs->perm_audio_reader, TRUE);
2314}
2315
2316
2317void 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
2347
2348// playback via memory buffers (e.g. in multitrack)
2349
2352
2353static 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
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
2365static 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
2401 return aframe_to_atstate_inner(event, NULL);
2402}
2403
2404
2406 return aframe_to_atstate_inner(event, ntracks);
2407}
2408
2409
2419lives_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));
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)) {
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
2567void 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++;
2697
2698 last_tc = fill_tc;
2699
2700 pthread_mutex_lock(&mainw->abuf_mutex);
2701 if (mainw->abufs_to_fill > 0) {
2703 }
2704 pthread_mutex_unlock(&mainw->abuf_mutex);
2705}
2706
2707
2708void init_jack_audio_buffers(int achans, int arate, boolean exact) {
2709#ifdef ENABLE_JACK
2710
2711 int chan;
2712
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
2729void init_pulse_audio_buffers(int achans, int arate, boolean exact) {
2730#ifdef HAVE_PULSE_AUDIO
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
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
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
2786#ifdef RESEEK_ENABLE
2792 return;
2793 }
2794
2795 if (!pthread_mutex_trylock(&mainw->avseek_mutex)) {
2800 }
2801 pthread_mutex_unlock(&mainw->avseek_mutex);
2802 }
2803#endif
2804}
2805
2806
2822boolean 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
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
2836 && mainw->current_file != mainw->pulsed->playing_file)
2837#endif
2838 ||
2839#ifdef ENABLE_JACK
2841 && mainw->current_file != mainw->jackd->playing_file) ||
2842#endif
2843 0))
2844 return FALSE;
2845
2846#ifdef ENABLE_JACK
2848 if (!jack_audio_seek_frame(mainw->jackd, frameno)) {
2849 if (jack_try_reconnect()) jack_audio_seek_frame(mainw->jackd, frameno);
2851 }
2853
2855 jack_get_rec_avals(mainw->jackd);
2856 }
2857 return TRUE;
2858 }
2859#endif
2860
2861#ifdef HAVE_PULSE_AUDIO
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);
2869 }
2871
2873 pulse_get_rec_avals(mainw->pulsed);
2874 }
2875 return TRUE;
2876 }
2877#endif
2878 return FALSE;
2879}
2880
2881
2883static lives_audio_buf_t *cache_buffer = NULL;
2884static pthread_t athread;
2885
2886static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
2887static pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER;
2888
2889
2904static 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
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
2930
2931#ifdef ENABLE_JACK
2933 mainw->jackd->abufs[mainw->write_abuf]->samples_filled = 0;
2935 continue;
2936 }
2937#endif
2938#ifdef HAVE_PULSE_AUDIO
2940 mainw->pulsed->abufs[mainw->write_abuf]->samples_filled = 0;
2942 continue;
2943 }
2944#endif
2945
2946 if (cbuffer->operation != LIVES_READ_OPERATION) {
2947 cbuffer->is_ready = TRUE;
2948 continue;
2949 }
2950
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;
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.) {
3151 } else {
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
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
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
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;
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
3319 jack_pb_end();
3320 }
3321#endif
3322}
3323
3325 return cache_buffer;
3326}
3327
3329
3330// plugin handling
3331
3332boolean 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
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
3356getaud1:
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))
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) {
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])) {
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
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) {
3458 mainw->agen_key = agen_key;
3459 }
3460 weed_instance_unref(inst);
3461}
3462
3463
3465// apply audio as "rendered effect"
3466
3467static int audio_fd;
3468static char *audio_file;
3469
3471
3472weed_timecode_t aud_tc;
3473
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)) {
3484 return FALSE;
3485 }
3486 }
3487
3488 audio_pos = (double)((cfile->start - 1) * cfile->arate * cfile->achans * cfile->asampsize / 8) / cfile->fps;
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
3507void 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
3514boolean 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,
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
3614 weed_layer_set_audio_data(layer, fltbuf, cfile->arate, cfile->achans, onframes);
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
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
3688boolean 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,
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,
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
3823// audio streaming, older API
3824
3826
3827boolean 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
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
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
3888#ifdef HAVE_PULSE_AUDIO
3889 mainw->pulsed->astream_fd = afd;
3890#endif
3891 }
3892
3893#ifdef ENABLE_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
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
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
3930 if (mainw->jackd->astream_fd > -1) close(mainw->jackd->astream_fd);
3931 mainw->jackd->astream_fd = -1;
3932 }
3933#endif
3934
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
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
3964LIVES_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
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"),
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 {
3989 }
3990#endif
3991 } else {
3992 do_error_dialog(msg);
3996 }
3997 lives_free(msg);
3998 lives_free(msg2);
3999 return CANCEL_ERROR;
4000}
4001
4002
4003#if 0
4004void 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;
4010}
4011
4012
4013void nullaudio_arate_set(int arate) {
4014 mainw->nullaudio_arate = arate;
4015}
4016
4017
4018void nullaudio_seek_set(offs64_t seek_posn) {
4019 // (virtual) seek posn in bytes
4020 mainw->nullaudio_seek_posn = seek_posn;
4021}
4022
4023
4024void nullaudio_clip_set(int clipno) {
4025 mainw->nullaudio_playing_file = clipno;
4026}
4027
4028
4029int64_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) {
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) {
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
4068void 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
4079static 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
void audio_free_fnames(void)
Definition: audio.c:71
void append_to_audio_bufferf(float *src, uint64_t nsamples, int channum)
Definition: audio.c:82
boolean apply_rte_audio(int64_t nframes)
Definition: audio.c:3514
weed_timecode_t aud_tc
Definition: audio.c:3472
LIVES_LOCAL_INLINE lives_audio_track_state_t * aframe_to_atstate(weed_plant_t *event)
Definition: audio.c:2400
void init_audio_frame_buffers(short aplayer)
Definition: audio.c:155
boolean get_audio_from_plugin(float **fbuffer, int nchans, int arate, int nsamps, boolean is_audio_thread)
Definition: audio.c:3332
int64_t sample_move_abuf_float(float **obuf, int nchans, int nsamps, int out_arate, float vol)
copy audio data from cache into audio sound buffer
Definition: audio.c:888
void append_to_audio_buffer16(void *src, uint64_t nsamples, int channum)
Definition: audio.c:118
void sample_move_float_float(float *dst, float *src, uint64_t nsamples, double scale, int dst_skip)
Definition: audio.c:745
void wake_audio_thread(void)
Definition: audio.c:3230
void audio_cache_end(void)
Definition: audio.c:3276
int64_t 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)
render a chunk of audio, apply effects and mixing it
Definition: audio.c:1276
LIVES_GLOBAL_INLINE char * get_achannel_name(int totchans, int idx)
Definition: audio.c:28
boolean resync_audio(double frameno)
resync audio playback to the current video frame
Definition: audio.c:2822
void preview_audio(void)
Definition: audio.c:1835
float audiofile_get_maxvol(int fnum, double start, double end, float thresh)
Definition: audio.c:248
boolean push_audio_to_channel(weed_plant_t *filter, weed_plant_t *achan, lives_audio_buf_t *abuf)
fill the audio channel(s) for effects with mixed audio / video
Definition: audio.c:3688
LIVES_LOCAL_INLINE void audio_process_events_to(weed_timecode_t tc)
Definition: audio.c:1241
void fill_abuffer_from(lives_audio_buf_t *abuf, weed_plant_t *event_list, weed_plant_t *st_event, boolean exact)
Definition: audio.c:2567
void preview_aud_vol(void)
Definition: audio.c:1991
LIVES_GLOBAL_INLINE lives_audio_track_state_t * audio_frame_to_atstate(weed_event_t *event, int *ntracks)
Definition: audio.c:2405
LIVES_GLOBAL_INLINE void audio_stream(void *buff, size_t nbytes, int fd)
Definition: audio.c:3964
LIVES_GLOBAL_INLINE void avsync_force(void)
Definition: audio.c:2785
boolean start_audio_stream(void)
Definition: audio.c:3827
void init_jack_audio_buffers(int achans, int arate, boolean exact)
Definition: audio.c:2708
lives_pgid_t astream_pgid
Definition: audio.c:3825
void aud_fade(int fileno, double startt, double endt, double startv, double endv)
fade in/fade out
Definition: audio.c:1813
void reinit_audio_gen(void)
Definition: audio.c:3449
LIVES_GLOBAL_INLINE const char * audio_player_get_display_name(const char *aplayer)
Definition: audio.c:65
float get_float_audio_val_at_time(int fnum, int afd, double secs, int chnum, int chans)
Definition: audio.c:374
void sample_silence_stream(int nchans, int64_t nframes)
Definition: audio.c:421
void stop_audio_stream(void)
Definition: audio.c:3906
void init_pulse_audio_buffers(int achans, int arate, boolean exact)
Definition: audio.c:2729
LIVES_GLOBAL_INLINE char * get_audio_file_name(int fnum, boolean opening)
Definition: audio.c:38
void free_audio_frame_buffer(lives_audio_buf_t *abuf)
Definition: audio.c:207
lives_audio_buf_t * audio_cache_init(void)
Definition: audio.c:3238
int64_t 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)
convert float samples back to int interleaved is for the float buffer; output int is always interleav...
Definition: audio.c:793
LIVES_GLOBAL_INLINE lives_audio_buf_t * audio_cache_get_buffer(void)
Definition: audio.c:3324
void free_pulse_audio_buffers(void)
Definition: audio.c:2768
boolean adjust_clip_volume(int fileno, float newvol, boolean make_backup)
Definition: audio.c:2001
#define CLIP_DECAY
Definition: audio.c:776
void clear_audio_stream(void)
Definition: audio.c:3949
float sample_move_d16_float(float *dst, short *src, uint64_t nsamples, uint64_t src_skip, int is_unsigned, boolean rev_endian, float vol)
Definition: audio.c:677
void 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)
convert from any number of source channels to any number of destination channels - both interleaved
Definition: audio.c:524
LIVES_GLOBAL_INLINE char * lives_get_audio_file_name(int fnum)
Definition: audio.c:55
void free_jack_audio_buffers(void)
Definition: audio.c:2748
void sample_move_d16_d8(uint8_t *dst, short *src, uint64_t nsamples, size_t tbytes, double scale, int nDstChannels, int nSrcChannels, int swap_sign)
convert from any number of source channels to any number of destination channels - 8 bit output
Definition: audio.c:617
boolean normalise_audio(int fnum, double start, double end, float thresh)
Definition: audio.c:280
boolean pad_with_silence(int out_fd, void *buff, off64_t oins_size, int64_t ins_size, int asamps, int aunsigned, boolean big_endian)
Definition: audio.c:1159
LIVES_GLOBAL_INLINE lives_cancel_t handle_audio_timeout(void)
Definition: audio.c:3971
boolean float_deinterleave(float *fbuffer, int nsamps, int nchans)
Definition: audio.c:1107
LIVES_GLOBAL_INLINE void sample_silence_dS(float *dst, uint64_t nsamples)
Definition: audio.c:415
off64_t audio_pos
Definition: audio.c:3470
void sample_move_d8_d16(short *dst, uint8_t *src, uint64_t nsamples, size_t tbytes, double scale, int nDstChannels, int nSrcChannels, int swap_sign)
Definition: audio.c:459
void apply_rte_audio_end(boolean del)
Definition: audio.c:3507
boolean float_interleave(float *fbuffer, int nsamps, int nchans)
Definition: audio.c:1125
boolean apply_rte_audio_init(void)
Definition: audio.c:3474
lives_audio_track_state_t * 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)
get audio (and optionally video) state at timecode tc OR before event st_event
Definition: audio.c:2419
int64_t sample_move_abuf_int16(short *obuf, int nchans, int nsamps, int out_arate)
copy audio data from cache into audio sound buffer
Definition: audio.c:993
#define MAX_AUDIO_MEM
TODO ** - make configurable - audio buffer size for rendering.
Definition: audio.h:36
#define SILENCE_BLOCK_SIZE
size of silent block in bytes
Definition: audio.h:42
#define SAMPLE_MAX_16BIT_P
Definition: audio.h:10
#define RENDER_BLOCK_SIZE
chunk size for interpolate/effect cycle
Definition: audio.h:39
#define XSAMPLES
buffer size (output samples) for (semi) realtime audio (bytes == XSAMPLES * achans * samp....
Definition: audio.h:47
#define SAMPLE_MAX_16BITI
Definition: audio.h:12
#define SWAP_L_TO_X
local to other
Definition: audio.h:20
#define NSTOREDFDS
Definition: audio.h:33
#define WEED_LEAF_HOST_KEEP_ADATA
Definition: audio.h:51
#define ASERVER_CMD_FILE_CLOSE
Definition: audio.h:58
#define is_realtime_aplayer(ptype)
Definition: audio.h:236
#define SAMPLE_MAX_16BIT_N
Definition: audio.h:11
#define DEFAULT_AUDIO_CHANS
Definition: audio.h:24
@ LIVES_READ_OPERATION
Definition: audio.h:71
#define lives_vol_from_linear(vol)
Definition: audio.h:269
#define DEFAULT_AUDIO_RATE
defaults for when not specifed
Definition: audio.h:23
lives_rec_audio_type_t
Definition: audio.h:195
@ RECA_WINDOW_GRAB
Definition: audio.h:197
@ RECA_GENERATED
Definition: audio.h:201
@ RECA_EXTERNAL
Definition: audio.h:200
@ RECA_NEW_CLIP
Definition: audio.h:198
#define SWAP_X_TO_L
endian swapping
Definition: audio.h:19
#define SWAP_U_TO_S
sign swapping
Definition: audio.h:15
#define SWAP_S_TO_U
signed to unsigned
Definition: audio.h:16
@ AUDIO_LOOP_NONE
Definition: audio.h:146
@ AUDIO_LOOP_PINGPONG
Definition: audio.h:148
void on_playsel_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:4566
LIVES_GLOBAL_INLINE weed_layer_t * weed_layer_free(weed_layer_t *layer)
frees pixel_data for a layer, then the layer itself
LIVES_GLOBAL_INLINE weed_layer_t * weed_layer_new(int layer_type)
Definition: colourspace.c:9655
LIVES_GLOBAL_INLINE float ** weed_layer_get_audio_data(weed_layer_t *layer, int *naudchans)
LIVES_GLOBAL_INLINE int weed_layer_get_audio_length(weed_layer_t *layer)
LIVES_GLOBAL_INLINE weed_layer_t * weed_layer_set_audio_data(weed_layer_t *layer, float **data, int arate, int naudchans, weed_size_t nsamps)
Definition: colourspace.c:9681
#define WEED_LAYER_TYPE_AUDIO
Definition: colourspace.h:222
weed_plant_t weed_layer_t
Definition: colourspace.h:71
void do_write_failed_error_s(const char *s, const char *addinfo)
Definition: dialogs.c:3979
LIVES_GLOBAL_INLINE LiVESResponseType do_abort_cancel_retry_dialog(const char *text)
Definition: dialogs.c:708
boolean do_auto_dialog(const char *text, int type)
Definition: dialogs.c:2844
LiVESResponseType do_write_failed_error_s_with_retry(const char *fname, const char *errtext)
Definition: dialogs.c:4058
void do_read_failed_error_s(const char *s, const char *addinfo)
Definition: dialogs.c:4034
LIVES_GLOBAL_INLINE LiVESResponseType do_error_dialog(const char *text)
Definition: dialogs.c:749
void threaded_dialog_spin(double fraction)
Definition: dialogs.c:3823
boolean pconx_chain_data(int key, int mode, boolean is_audio_thread)
LIVES_GLOBAL_INLINE int filter_mutex_unlock(int key)
Definition: effects-weed.c:108
int rte_key_getmode(int key)
returns current active mode for a key (or -1)
weed_plant_t * weed_instance_get_filter(weed_plant_t *inst, boolean get_compound_parent)
Definition: effects-weed.c:180
void weed_apply_audio_effects_rt(weed_layer_t *alayer, weed_timecode_t tc, boolean analysers_only, boolean is_audio_thread)
weed_plant_t * rte_keymode_get_instance(int key, int mode)
returns refcounted filter_instance bound to key/mode (or NULL)
int weed_get_idx_for_hashname(const char *hashname, boolean fullname)
fullname includes author and version
boolean has_audio_chans_out(weed_plant_t *filter, boolean count_opt)
Definition: effects-weed.c:695
lives_filter_error_t run_process_func(weed_plant_t *instance, weed_timecode_t tc, int key)
LIVES_GLOBAL_INLINE int weed_instance_unref(weed_plant_t *inst)
weed_plant_t * get_weed_filter(int idx)
weed_plant_t * weed_inst_in_param(weed_plant_t *inst, int param_num, boolean skip_hidden, boolean skip_internal)
void weed_apply_audio_effects(weed_plant_t *filter_map, weed_layer_t **layers, int nbtracks, int nchans, int64_t nsamps, double arate, weed_timecode_t tc, double *vis)
weed_plant_t * get_enabled_channel(weed_plant_t *inst, int which, boolean is_in)
for FILTER_INST
Definition: effects-weed.c:536
boolean has_audio_filters(lives_af_t af_type)
boolean is_pure_audio(weed_plant_t *plant, boolean count_opt)
TRUE if audio in or out and no vid in/out.
Definition: effects-weed.c:714
lives_filter_error_t weed_reinit_effect(weed_plant_t *inst, boolean reinit_compound)
@ FILTER_SUCCESS
Definition: effects-weed.h:15
@ FILTER_INFO_REINITED
values >= 512 are info
Definition: effects-weed.h:40
#define WEED_LEAF_HOST_NEXT_INSTANCE
Definition: effects-weed.h:104
#define WEED_LEAF_HOST_TAG
Definition: effects-weed.h:66
@ AF_TYPE_NONA
Definition: effects.h:43
double * get_track_visibility_at_tc(weed_plant_t *event_list, int ntracks, int nbtracks, weed_timecode_t tc, weed_plant_t **shortcut, boolean bleedthru)
calculate the "visibility" of each track at timecode tc
Definition: events.c:5400
weed_plant_t * get_next_audio_frame_event(weed_plant_t *event)
Definition: events.c:380
LIVES_GLOBAL_INLINE weed_timecode_t weed_event_get_timecode(weed_event_t *event)
Definition: events.c:89
weed_plant_t * process_events(weed_plant_t *next_event, boolean process_audio, weed_timecode_t curr_tc)
Definition: events.c:3082
LIVES_GLOBAL_INLINE int weed_event_get_type(weed_event_t *event)
Definition: events.c:31
LIVES_GLOBAL_INLINE weed_plant_t * get_first_event(weed_plant_t *event_list)
Definition: events.c:119
LIVES_GLOBAL_INLINE weed_timecode_t get_event_timecode(weed_plant_t *plant)
Definition: events.c:98
LIVES_GLOBAL_INLINE weed_plant_t * get_next_event(weed_plant_t *event)
Definition: events.c:114
LIVES_GLOBAL_INLINE int weed_frame_event_get_audio_tracks(weed_event_t *event, int **clips, double **seeks)
Definition: events.c:59
#define AUD_DIFF_MIN
ignore audio seek differences < than this (seconds)
Definition: events.h:94
#define WEED_LEAF_DEINIT_EVENT
Definition: events.h:76
#define WEED_EVENT_IS_AUDIO_FRAME(event)
Definition: events.h:362
#define WEED_LEAF_INIT_EVENT
Definition: events.h:52
#define WEED_LEAF_FILTER
Definition: events.h:44
#define WEED_LEAF_IN_TRACKS
Definition: events.h:47
weed_plant_t weed_event_t
Definition: events.h:97
#define WEED_LEAF_INDEX
Definition: events.h:58
double lives_ce_update_timeline(int frame, double x)
pointer position in timeline
Definition: interface.c:207
#define LIVES_PREVIEW_TYPE_VIDEO_ONLY
Definition: interface.h:171
#define LIVES_PREVIEW_TYPE_VIDEO_AUDIO
Definition: interface.h:170
#define LIVES_PREVIEW_TYPE_AUDIO_ONLY
Definition: interface.h:172
LIVES_GLOBAL_INLINE void * lives_calloc_safety(size_t nmemb, size_t xsize)
Definition: machinestate.c:603
off_t get_file_size(int fd)
Definition: machinestate.c:943
LIVES_GLOBAL_INLINE ticks_t lives_get_current_ticks(void)
Definition: machinestate.c:835
LIVES_GLOBAL_INLINE void swab2(const void *from, const void *to, size_t gran)
LIVES_GLOBAL_INLINE uint64_t fastrand(void)
Definition: machinestate.c:40
boolean reverse_buffer(uint8_t *buff, size_t count, size_t chunk)
#define EXTRA_BYTES
TODO - split into: memory, files, sysops, threads.
Definition: machinestate.h:16
#define lives_nanosleep(nanosec)
Definition: machinestate.h:307
#define lives_calloc
Definition: machinestate.h:67
#define THREADVAR(var)
Definition: machinestate.h:531
#define lives_free
Definition: machinestate.h:52
#define lives_memset
Definition: machinestate.h:61
#define lives_memcpy
Definition: machinestate.h:55
#define lives_realloc
Definition: machinestate.h:49
ssize_t sizdbl
Definition: main.c:102
ssize_t sizint
type sizes
Definition: main.c:102
mainwindow * mainw
Definition: main.c:103
ssize_t lives_read_buffered(int fd, void *buf, ssize_t count, boolean allow_less)
Definition: utils.c:924
#define LIVES_WARN(x)
Definition: main.h:1862
int lives_close_buffered(int fd)
Definition: utils.c:716
lives_pid_t lives_fork(const char *com)
Definition: utils.c:288
ssize_t lives_write(int fd, livesconstpointer buf, ssize_t count, boolean allow_fail)
@ STOP_ON_AUD_END
Definition: main.h:695
off_t lives_lseek_buffered_writer(int fd, off_t offset)
Definition: utils.c:1338
#define LIVES_GLOBAL_INLINE
Definition: main.h:239
#define AFORM_SIGNED
Definition: main.h:783
ticks_t lives_get_current_playback_ticks(ticks_t origsecs, ticks_t origusecs, lives_time_source_t *time_source)
Definition: utils.c:1481
@ CANCEL_KILL
normal - kill background processes working on current clip
Definition: main.h:759
@ CANCEL_SOFT
just cancel in GUI (for keep, etc)
Definition: main.h:760
ssize_t lives_write_buffered(int fd, const char *buf, ssize_t count, boolean allow_fail)
Definition: utils.c:1226
#define DEF_FILE_PERMS
non-executable, is modified by the umask
Definition: main.h:209
#define LIVES_IS_PLAYING
Definition: main.h:840
#define IS_NORMAL_CLIP(clip)
Definition: main.h:833
#define LIVES_CLIP_HEADER_VERSION
Definition: main.h:941
size_t lives_buffered_orig_size(int fd)
Definition: utils.c:1377
int lives_open3(const char *pathname, int flags, mode_t mode)
Definition: utils.c:94
#define CURRENT_CLIP_HAS_AUDIO
Definition: main.h:818
boolean lives_alarm_clear(lives_alarm_t alarm_handle)
Definition: utils.c:1732
#define LIVES_LOCAL_INLINE
Definition: main.h:246
int lives_system(const char *com, boolean allow_error)
Definition: utils.c:145
int lives_killpg(lives_pgid_t pgrp, int sig)
Definition: utils.c:1432
void switch_aud_to_none(boolean set_pref)
Definition: utils.c:4001
#define AFORM_UNSIGNED
Definition: main.h:786
#define AFORM_LITTLE_ENDIAN
Definition: main.h:784
int lives_open_buffered_rdonly(const char *pathname)
Definition: utils.c:636
#define SIGNED_DIVIDE(a, b)
Definition: main.h:295
@ CLIP_DETAILS_ASAMPS
Definition: main.h:1153
@ CLIP_DETAILS_ASIGNED
Definition: main.h:1151
@ CLIP_DETAILS_ACHANS
Definition: main.h:1150
@ CLIP_DETAILS_AENDIAN
Definition: main.h:1152
@ CLIP_DETAILS_PB_ARATE
Definition: main.h:1149
@ CLIP_DETAILS_ARATE
Definition: main.h:1148
@ CLIP_DETAILS_HEADER_VERSION
Definition: main.h:1161
lives_alarm_t lives_alarm_set(ticks_t ticks)
set alarm for now + delta ticks (10 nanosec) param ticks (10 nanoseconds) is the offset when we want ...
Definition: utils.c:1643
#define IS_VALID_CLIP(clip)
Definition: main.h:808
int lives_rm(const char *file)
Definition: utils.c:4395
int64_t ticks_t
Definition: main.h:97
void d_print_failed(void)
Definition: utils.c:2615
capability * capable
Definition: main.h:627
#define cfile
Definition: main.h:1833
off_t lives_buffered_offset(int fd)
Definition: utils.c:1364
int lives_open2(const char *pathname, int flags)
Definition: utils.c:99
void d_print(const char *fmt,...)
Definition: utils.c:2542
int lives_open_buffered_writer(const char *pathname, int mode, boolean append)
Definition: utils.c:706
int lives_pgid_t
Definition: main.h:118
boolean lives_buffered_rdonly_set_reversed(int fd, boolean val)
Definition: utils.c:681
#define CLIP_AUDIO_TIME(clip)
Definition: main.h:827
#define AFORM_BIG_ENDIAN
Definition: main.h:787
off_t lives_lseek_buffered_rdonly(int fd, off_t offset)
Definition: utils.c:895
off_t lives_lseek_buffered_rdonly_absolute(int fd, off_t offset)
Definition: utils.c:907
uint32_t get_signed_endian(boolean is_signed, boolean little_endian)
produce bitmapped value
Definition: utils.c:5408
boolean lives_freep(void **ptr)
Definition: utils.c:1411
boolean save_clip_value(int which, lives_clip_details_t, void *val)
Definition: utils.c:5175
ticks_t lives_alarm_check(lives_alarm_t alarm_handle)
Definition: utils.c:1687
lives_cancel_t
cancel reason
Definition: main.h:699
@ CANCEL_AUD_END
video playback completed
Definition: main.h:737
@ CANCEL_NONE
no cancel
Definition: main.h:701
@ CANCEL_ERROR
cancelled because of error
Definition: main.h:740
@ CANCEL_AUDIO_ERROR
cancelled because of soundcard error
Definition: main.h:743
#define ONE_MILLION_DBL
Definition: mainwindow.h:32
#define LIVES_SIGKILL
Definition: mainwindow.h:1854
#define USEC_TO_TICKS
multiplying factor uSec -> ticks_t (def. 100)
Definition: mainwindow.h:38
#define PLUGIN_EXEC_DIR
Definition: mainwindow.h:599
#define CLIP_TEMP_AUDIO_FILENAME
Definition: mainwindow.h:538
#define TICKS_PER_SECOND_DBL
actually microseconds / 100.
Definition: mainwindow.h:37
#define ONE_MILLION
Definition: mainwindow.h:27
#define CLIP_AUDIO_FILENAME
Definition: mainwindow.h:537
#define LIVES_DEFAULT_TIMEOUT
Definition: mainwindow.h:43
int lives_alarm_t
Definition: mainwindow.h:696
#define MAX_AUDIO_TRACKS
Definition: multitrack.h:1046
#define PLUGIN_AUDIO_STREAM
Definition: plugins.h:101
#define AUDIO_PLAYER_PULSE_AUDIO
used for display, alternate pref and alternate startup opt (-aplayer pulseaudio)
Definition: preferences.h:52
_prefs * prefs
Definition: preferences.h:847
#define AUDIO_PLAYER_PULSE
used in pref and for external players (e.g -ao pulse, -aplayer pulse)
Definition: preferences.h:51
#define AUD_PLAYER_NONE
Definition: preferences.h:41
#define AUDIO_OPTS_FOLLOW_FPS
Definition: preferences.h:256
#define AUD_PLAYER_JACK
Definition: preferences.h:43
#define AUDIO_SRC_EXT
Definition: preferences.h:206
#define AUDIO_SRC_INT
Definition: preferences.h:205
#define AUD_PLAYER_PULSE
Definition: preferences.h:44
LIVES_GLOBAL_INLINE off_t quant_abytes(double seek, int arate, int achans, int asampsize)
Definition: resample.c:66
boolean perm_audio_reader
Definition: preferences.h:426
volatile uint32_t audio_opts
Definition: preferences.h:254
int audio_src
Definition: preferences.h:204
boolean push_audio_to_gens
Definition: preferences.h:424
char aplayer[512]
Definition: preferences.h:54
int num_rtaudiobufs
Definition: preferences.h:325
boolean force_system_clock
Definition: preferences.h:366
char workdir[PATH_MAX]
kept in locale encoding
Definition: preferences.h:61
char lib_dir[PATH_MAX]
Definition: preferences.h:75
int sleep_time
Definition: preferences.h:176
boolean show_dev_opts
Definition: preferences.h:463
boolean conserve_space
Definition: preferences.h:183
char backend_sync[PATH_MAX *4]
Definition: preferences.h:410
short audio_player
Definition: preferences.h:40
boolean(* render_audio_frame_float)(float **audio, int nsamps)
Definition: plugins.h:175
uint32_t audio_codec
Definition: plugins.h:169
pid_t mainpid
Definition: main.h:591
int byte_order
Definition: main.h:577
mode_t umask
Definition: main.h:597
double _shrink_factor
resampling ratio
Definition: audio.h:138
int32_t ** buffer32
sample data in 32 bit format (or NULL)
Definition: audio.h:114
int _fd
file descriptor
Definition: audio.h:131
ssize_t bytesize
Definition: audio.h:90
int _casamps
current out_asamps
Definition: audio.h:137
short ** buffer16
sample data in 16 bit format (or NULL)
Definition: audio.h:110
lives_operation_t operation
Definition: audio.h:77
float ** bufferf
sample data in float format (or NULL)
Definition: audio.h:115
boolean eof
did we read EOF ? [readonly by client]
Definition: audio.h:79
size_t _csamp_space
current sample buffer size in single channel samples
Definition: audio.h:130
int _cout_interleaf
Definition: audio.h:136
volatile boolean is_ready
Definition: audio.h:78
ssize_t _cbytesize
current _filebuffer bytesize; if this changes we need to realloc _filebuffer
Definition: audio.h:129
int in_achans
channels for _filebuffer side
Definition: audio.h:95
boolean out_interleaf
Definition: audio.h:93
int _cin_interleaf
Definition: audio.h:135
int32_t ** buffer24
sample data in 24 bit format (or NULL)
Definition: audio.h:113
volatile size_t samples_filled
number of samples filled (readonly client)
Definition: audio.h:124
int out_asamps
Definition: audio.h:98
boolean in_interleaf
Definition: audio.h:92
int out_achans
channels for buffer* side
Definition: audio.h:96
volatile boolean die
set to TRUE to shut down thread
Definition: audio.h:140
boolean s16_signed
Definition: audio.h:119
int _cachans
current output channels
Definition: audio.h:134
boolean sequential
hint that we will read sequentially starting from seek
Definition: audio.h:105
size_t start_sample
used for reading (readonly server)
Definition: audio.h:125
size_t samp_space
buffer space in samples (* by sizeof(type) to get bytesize) [if interleaf, also * by chans]
Definition: audio.h:103
int _cseek
current seek pos
Definition: audio.h:133
boolean s8_signed
Definition: audio.h:118
uint8_t * _filebuffer
raw data to/from file - can be cast to int16_t
Definition: audio.h:128
off_t seek
Definition: audio.h:85
uint8_t ** buffer8
sample data in 8 bit format (or NULL)
Definition: audio.h:108
double shrink_factor
resampling ratio
Definition: audio.h:101
int _cfileno
current fileno
Definition: audio.h:132
corresponds to one clip in the GUI
Definition: main.h:877
int arps
audio physical sample rate (i.e the "normal" sample rate of the clip when played at 1,...
Definition: main.h:905
int asampsize
audio sample size in bits (8 or 16)
Definition: main.h:908
int header_version
Definition: main.h:940
int achans
number of audio channels (0, 1 or 2)
Definition: main.h:907
int cb_src
source clip for clipboard; for other clips, may be used to hold some temporary linkage
Definition: main.h:1086
double laudio_time
Definition: main.h:929
uint32_t signed_endian
bitfield
Definition: main.h:909
int arate
current audio playback rate (varies if the clip rate is changed)
Definition: main.h:906
float vol
relative volume level / gain; sizeof array will be equal to achans
Definition: main.h:910
char handle[256]
Definition: main.h:881
boolean opening
Definition: main.h:946
_vid_playback_plugin * vpp
video plugin
Definition: mainwindow.h:1572
volatile int agen_key
which fx key is generating audio [1 based] (or 0 for none)
Definition: mainwindow.h:1649
pthread_mutex_t abuf_frame_mutex
used to synch audio buffer for generators
Definition: mainwindow.h:1496
boolean aplayer_broken
Definition: mainwindow.h:1653
volatile boolean video_seek_ready
Definition: mainwindow.h:939
int write_abuf
audio buffer number to write to (for multitrack)
Definition: mainwindow.h:1591
double aframeno
and the audio 'frame' for when we are looping
Definition: mainwindow.h:962
pthread_mutex_t audio_filewriteend_mutex
sync for ending writing audio to file
Definition: mainwindow.h:1503
int aud_rec_fd
fd of file we are recording audio to
Definition: mainwindow.h:1525
volatile ticks_t currticks
wall clock time, updated whenever lives_get_*_ticks is called
Definition: mainwindow.h:1005
void * pulsed
pulseaudio player
Definition: mainwindow.h:1463
lives_clip_t * files[MAX_FILES+1]
+1 for the clipboard
Definition: mainwindow.h:729
volatile boolean record
Definition: mainwindow.h:794
ticks_t origsecs
playback start seconds - subtracted from all other ticks to keep numbers smaller
Definition: mainwindow.h:1000
boolean is_rendering
Definition: mainwindow.h:821
volatile double rec_avel
Definition: mainwindow.h:968
volatile boolean ext_audio
using external video playback plugin to stream audio
Definition: mainwindow.h:774
volatile lives_cancel_t cancelled
Definition: mainwindow.h:798
boolean preview
Definition: mainwindow.h:757
int current_file
Definition: mainwindow.h:727
lives_cancel_type_t cancel_type
Definition: mainwindow.h:799
ticks_t orignsecs
usecs at start of playback - ditto
Definition: mainwindow.h:1001
void * jackd
jack audio player / transport
Definition: mainwindow.h:1453
uint64_t agen_samps_count
count of samples since init
Definition: mainwindow.h:1651
lives_audio_buf_t * afb[2]
used for buffering / feeding audio to video generators
Definition: mainwindow.h:1698
weed_plant_t * filter_map
Definition: mainwindow.h:1298
void * pulsed_read
Definition: mainwindow.h:1464
pthread_mutex_t vpp_stream_mutex
prevent from writing audio when stream is closing
Definition: mainwindow.h:1501
double fx1_val
Definition: mainwindow.h:1049
boolean error
Definition: mainwindow.h:801
boolean suppress_dprint
tidy up, e.g. by blocking "switched to file..." and "closed file..." messages
Definition: mainwindow.h:1537
weed_plant_t * audio_event
Definition: mainwindow.h:1300
pthread_mutex_t abuf_mutex
mutices
Definition: mainwindow.h:1495
frames_t play_start
Definition: mainwindow.h:931
volatile int rec_aclip
recording values - to be inserted at the following video frame
Definition: mainwindow.h:967
volatile double rec_aseek
Definition: mainwindow.h:969
boolean playing_sel
list of set names in current workdir, mau be NULL
Definition: mainwindow.h:756
volatile boolean record_paused
pause during recording
Definition: mainwindow.h:1557
int ascrap_file
scrap file for recording audio scraps
Definition: mainwindow.h:875
lives_mt * multitrack
holds a pointer to the entire multitrack environment; NULL in Clip Edit mode
Definition: mainwindow.h:1087
pthread_mutex_t avseek_mutex
Definition: mainwindow.h:938
boolean foreign
for external window capture
Definition: mainwindow.h:824
volatile boolean agen_needs_reinit
Definition: mainwindow.h:1650
pthread_mutex_t cache_buffer_mutex
sync for jack playback termination
Definition: mainwindow.h:1502
boolean preview_rendering
Definition: mainwindow.h:758
volatile int abufs_to_fill
Definition: mainwindow.h:1592
frames_t play_end
Definition: mainwindow.h:931
boolean force_show
Definition: mainwindow.h:1763
ticks_t deltaticks
deltaticks for scratching
Definition: mainwindow.h:1006
volatile ticks_t startticks
effective ticks when current frame was (should have been) displayed
Definition: mainwindow.h:997
weed_plant_t * afilter_map
Definition: mainwindow.h:1299
volatile boolean audio_seek_ready
Definition: mainwindow.h:940
lives_pconnect_t * pconx
list of out -> in param connections
Definition: mainwindow.h:1668
volatile lives_whentostop_t whentostop
Definition: mainwindow.h:929
int playing_file
which number file we are playing (or -1) [generally mainw->current_file]
Definition: mainwindow.h:943
pthread_mutex_t fx_mutex[FX_KEYS_MAX]
used to prevent fx processing when it is scheduled for deinit
Definition: mainwindow.h:1497
volatile lives_audio_buf_t * audio_frame_buffer
used for buffering / feeding audio to video generators
Definition: mainwindow.h:1697
void * jackd_read
dummy
Definition: mainwindow.h:1454
weed_event_t * event_list
current event_list, for recording
Definition: mainwindow.h:803
#define lives_strdup_printf(fmt,...)
Definition: support.c:27
#define _(String)
Definition: support.h:44
#define TRUE
Definition: videoplugin.h:59
#define FALSE
Definition: videoplugin.h:60
WEED_GLOBAL_INLINE int weed_chantmpl_get_flags(weed_plant_t *chantmpl)
WEED_GLOBAL_INLINE weed_plant_t * weed_channel_get_template(weed_plant_t *channel)
WEED_GLOBAL_INLINE weed_layer_t * weed_channel_set_audio_data(weed_plant_t *channel, float **data, int arate, int naudchans, int nsamps)
WEED_GLOBAL_INLINE int weed_filter_get_flags(weed_plant_t *filter)
WEED_GLOBAL_INLINE int weed_chantmpl_get_max_audio_length(weed_plant_t *chantmpl)