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 
14 static char *storedfnames[NSTOREDFDS];
15 static int storedfds[NSTOREDFDS];
16 static boolean storedfdsset = FALSE;
17 
18 
19 static void audio_reset_stored_fnames(void) {
20  for (int i = 0; i < NSTOREDFDS; i++) {
21  storedfnames[i] = NULL;
22  storedfds[i] = -1;
23  }
24  storedfdsset = TRUE;
25 }
26 
27 
28 LIVES_GLOBAL_INLINE char *get_achannel_name(int totchans, int idx) {
29  if (totchans == 1) return (_("Mono"));
30  if (totchans == 2) {
31  if (idx == 0) return (_("Left channel"));
32  if (idx == 1) return (_("Right channel"));
33  }
34  return lives_strdup_printf(_("Audio channel %d"), idx);
35 }
36 
37 
38 LIVES_GLOBAL_INLINE char *get_audio_file_name(int fnum, boolean opening) {
39  char *fname;
40  if (!opening) {
41  if (IS_VALID_CLIP(fnum))
42  fname = lives_build_filename(prefs->workdir, mainw->files[fnum]->handle, CLIP_AUDIO_FILENAME, NULL);
43  else
44  fname = lives_build_filename(prefs->workdir, CLIP_AUDIO_FILENAME, NULL);
45  } else {
46  if (IS_VALID_CLIP(fnum))
47  fname = lives_build_filename(prefs->workdir, mainw->files[fnum]->handle, CLIP_TEMP_AUDIO_FILENAME, NULL);
48  else
49  fname = lives_build_filename(prefs->workdir, CLIP_TEMP_AUDIO_FILENAME, NULL);
50  }
51  return fname;
52 }
53 
54 
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 
65 LIVES_GLOBAL_INLINE const char *audio_player_get_display_name(const char *aplayer) {
66  if (!strcmp(aplayer, AUDIO_PLAYER_PULSE)) return AUDIO_PLAYER_PULSE_AUDIO;
67  return aplayer;
68 }
69 
70 
71 void audio_free_fnames(void) {
72  // cleanup stored filehandles after playback/fade/render
73  if (!storedfdsset) return;
74  for (int i = 0; i < NSTOREDFDS; i++) {
75  lives_freep((void **)&storedfnames[i]);
76  if (storedfds[i] > -1) lives_close_buffered(storedfds[i]);
77  storedfds[i] = -1;
78  }
79 }
80 
81 
82 void append_to_audio_bufferf(float *src, uint64_t nsamples, int channum) {
83  // append float audio to the audio frame buffer
84  size_t nsampsize;
85  lives_audio_buf_t *abuf;
86 
87  if (!prefs->push_audio_to_gens) return;
88 
89  pthread_mutex_lock(&mainw->abuf_frame_mutex);
90 
91  abuf = (lives_audio_buf_t *)mainw->audio_frame_buffer; // this is a pointer to either mainw->afb[0] or mainw->afb[1]
92 
93  if (!abuf) {
94  pthread_mutex_unlock(&mainw->abuf_frame_mutex);
95  return;
96  }
97 
98  if (!abuf->bufferf) free_audio_frame_buffer(abuf);
99 
100  nsampsize = (abuf->samples_filled + nsamples);
101 
102  channum++;
103  if (channum > abuf->out_achans) {
104  int i;
105  abuf->bufferf = (float **)lives_realloc(abuf->bufferf, channum * sizeof(float *));
106  for (i = abuf->out_achans; i < channum; i++) {
107  abuf->bufferf[i] = NULL;
108  }
109  abuf->out_achans = channum;
110  }
111  channum--;
112  abuf->bufferf[channum] = (float *)lives_realloc(abuf->bufferf[channum], nsampsize * sizeof(float) + EXTRA_BYTES);
113  lives_memcpy(&abuf->bufferf[channum][abuf->samples_filled], src, nsamples * sizeof(float));
114  pthread_mutex_unlock(&mainw->abuf_frame_mutex);
115 }
116 
117 
118 void append_to_audio_buffer16(void *src, uint64_t nsamples, int channum) {
119  // append 16 bit audio to the audio frame buffer
120  size_t nsampsize;
121  lives_audio_buf_t *abuf;
122 
123  if (!prefs->push_audio_to_gens) return;
124 
125  pthread_mutex_lock(&mainw->abuf_frame_mutex);
126 
127  abuf = (lives_audio_buf_t *)mainw->audio_frame_buffer; // this is a pointer to either mainw->afb[0] or mainw->afb[1]
128 
129  if (!abuf) {
130  pthread_mutex_unlock(&mainw->abuf_frame_mutex);
131  return;
132  }
133  if (!abuf->buffer16) free_audio_frame_buffer(abuf);
134 
135  nsampsize = (abuf->samples_filled + nsamples);
136  channum++;
137  if (!abuf->buffer16 || channum > abuf->out_achans) {
138  int i;
139  abuf->buffer16 = (int16_t **)lives_calloc(channum, sizeof(short *));
140  for (i = abuf->out_achans; i < channum; i++) {
141  abuf->buffer16[i] = NULL;
142  }
143  abuf->out_achans = channum;
144  }
145  channum--;
146  abuf->buffer16[channum] = (short *)lives_realloc(abuf->buffer16[channum], nsampsize * sizeof(short) + EXTRA_BYTES);
147  lives_memcpy(&abuf->buffer16[channum][abuf->samples_filled], src, nsamples * 2);
148 #ifdef DEBUG_AFB
149  g_print("append16 to afb\n");
150 #endif
151  pthread_mutex_unlock(&mainw->abuf_frame_mutex);
152 }
153 
154 
155 void init_audio_frame_buffers(short aplayer) {
156  // function should be called when the first video generator with audio input is enabled
157  int i;
158 
159  for (i = 0; i < 2; i++) {
160  lives_audio_buf_t *abuf;
161  mainw->afb[i] = abuf = (lives_audio_buf_t *)lives_calloc(1, sizeof(lives_audio_buf_t));
162 
163  abuf->samples_filled = 0;
164  abuf->swap_endian = FALSE;
165  abuf->out_achans = 0;
166  abuf->start_sample = 0;
167 
168  switch (aplayer) {
169 #ifdef HAVE_PULSE_AUDIO
170  case AUD_PLAYER_PULSE:
171  abuf->in_interleaf = abuf->out_interleaf = TRUE;
172  abuf->s16_signed = TRUE;
173  if (mainw->pulsed_read) {
174  abuf->in_achans = abuf->out_achans = mainw->pulsed_read->in_achans;
175  abuf->arate = mainw->pulsed_read->in_arate;
176  } else if (mainw->pulsed) {
177  abuf->in_achans = abuf->out_achans = mainw->pulsed->out_achans;
178  abuf->arate = mainw->pulsed->out_arate;
179  }
180  break;
181 #endif
182 #ifdef ENABLE_JACK
183  case AUD_PLAYER_JACK:
184  abuf->in_interleaf = abuf->out_interleaf = FALSE;
185  if (mainw->jackd_read && mainw->jackd_read->in_use) {
186  abuf->in_achans = abuf->out_achans = mainw->jackd_read->num_input_channels;
187  abuf->arate = mainw->jackd_read->sample_in_rate;
188  } else if (mainw->jackd) {
189  abuf->in_achans = abuf->out_achans = mainw->jackd->num_output_channels;
190  abuf->arate = mainw->jackd->sample_out_rate;
191  }
192  break;
193 #endif
194  default:
195  break;
196  }
197  }
198 
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 
248 float audiofile_get_maxvol(int fnum, double start, double end, float thresh) {
249  if (!IS_NORMAL_CLIP(fnum) || !mainw->files[fnum]->achans || start >= mainw->files[fnum]->laudio_time) return -1.;
250  else {
251  double atime = start;
252  lives_clip_t *afile = mainw->files[fnum];
253  char *filename = lives_get_audio_file_name(mainw->current_file);
254  int afd = lives_open_buffered_rdonly(filename);
255  float xx = 0., xf;
256  int c;
257  lives_free(filename);
258  if (end == 0. || end > afile->laudio_time) end = afile->laudio_time;
259  while (atime <= end) {
260  for (c = 0; c < afile->achans; c++) {
261  if (afd == -1) {
262  THREADVAR(read_failed) = -2;
263  return -1.;
264  }
265  xf = fabsf(get_float_audio_val_at_time(fnum, afd, atime, c, afile->achans));
266  if (xf > xx) xx = xf;
267  if (thresh >= 0. && xx > thresh) {
269  return xx;
270  }
271  }
272  atime += 1. / afile->arps;
273  }
275  return xx;
276  }
277 }
278 
279 
280 boolean normalise_audio(int fnum, double start, double end, float thresh) {
281  if (!IS_NORMAL_CLIP(fnum)) return FALSE;
282  else {
283  float xx = audiofile_get_maxvol(fnum, start, end, -1.);
284  if (xx <= 0.) return FALSE;
285  if (1) {
286  lives_clip_t *afile = mainw->files[fnum];
287  double atime = start;
288  float fact = thresh / xx, val;
289  char *filename = lives_get_audio_file_name(mainw->current_file);
290  boolean xsigned = !(afile->signed_endian & AFORM_UNSIGNED);
291  boolean swap_endian = FALSE;
292  int afd, afd2;
293  int c, count = 0;
294 
295  THREADVAR(read_failed) = THREADVAR(write_failed) = 0;
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  }
364  lives_close_buffered(afd2);
365  }
366  if (mainw->cancelled != CANCEL_NONE || THREADVAR(read_failed) || THREADVAR(write_failed)) {
367  return FALSE;
368  }
369  return TRUE;
370  }
371 }
372 
373 
374 float get_float_audio_val_at_time(int fnum, int afd, double secs, int chnum, int chans) {
375  // return audio level between -1.0 and +1.0
376  // afd must be opened with lives_open_buffered_rdonly()
377  lives_clip_t *afile = mainw->files[fnum];
378  off_t apos;
379  uint8_t val8, val8b;
380  uint16_t val16;
381  float val;
382  size_t quant = afile->achans * afile->asampsize / 8;
383  size_t bytes = (size_t)(secs * (double)afile->arate) * quant;
384 
385  if (!bytes) return 0.;
386 
387  apos = ((size_t)(bytes / quant) * quant); // quantise
388 
389  apos += afile->asampsize / 8 * chnum;
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 
415 LIVES_GLOBAL_INLINE void sample_silence_dS(float *dst, uint64_t nsamples) {
416  // send silence to the jack player
417  lives_memset(dst, 0, nsamples * sizeof(float));
418 }
419 
420 
421 void sample_silence_stream(int nchans, int64_t nframes) {
422  float **fbuff = (float **)lives_calloc(nchans, sizeof(float *));
423  boolean memok = TRUE;
424  int i;
425 
426  for (i = 0; i < nchans; i++) {
427  fbuff[i] = (float *)lives_calloc(nframes, sizeof(float));
428  if (!fbuff[i]) memok = FALSE;
429  }
430  if (memok) {
431  pthread_mutex_lock(&mainw->vpp_stream_mutex);
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
459 void sample_move_d8_d16(short *dst, uint8_t *src,
460  uint64_t nsamples, size_t tbytes, double scale,
461  int nDstChannels, int nSrcChannels, int swap_sign) {
462  // convert 8 bit audio to 16 bit audio
463 
464  // endianess will be machine endian
465  static double rem = 0.f;
466  double src_offset_d = rem;
467  unsigned char *ptr;
468  unsigned char *src_end;
469  off_t src_offset_i = 0;
470  int ccount;
471  int nSrcCount, nDstCount;
472 
473  // take care of rounding errors
474  src_end = src + tbytes - nSrcChannels;
475 
476  if (!nSrcChannels) return;
477 
478  if (scale < 0.f) {
479  src_offset_d = ((double)nsamples * (-scale) - 1.f - rem);
480  src_offset_i = (off_t)src_offset_d * nSrcChannels;
481  }
482 
483  while (nsamples--) {
484  nSrcCount = nSrcChannels;
485  nDstCount = nDstChannels;
486  ccount = 0;
487 
488  /* loop until all of our destination channels are filled */
489  while (nDstCount) {
490  nSrcCount--;
491  nDstCount--;
492 
493  ptr = src + ccount + src_offset_i;
494  ptr = ptr > src ? (ptr < (src_end + ccount) ? ptr : (src_end + ccount)) : src;
495 
496  if (!swap_sign) *(dst++) = *(ptr) << 8;
497  else if (swap_sign == SWAP_U_TO_S) *(dst++) = ((short)(*(ptr)) - 128) << 8;
498  else *((unsigned short *)(dst++)) = ((short)(*(ptr)) + 128) << 8;
499  ccount++;
500 
501  /* if we ran out of source channels but not destination channels */
502  /* then start the src channels back where we were */
503  if (!nSrcCount && nDstCount) {
504  ccount = 0;
505  nSrcCount = nSrcChannels;
506  }
507  }
508 
509  /* advance the position */
510  src_offset_i = (off_t)((src_offset_d += scale) + .4999) * nSrcChannels;
511  }
512  rem = 0.f;
513  if (scale > 0.f) {
514  if (src_offset_d > src_offset_i) rem = src_offset_d - (double)src_offset_i;
515  } else {
516  if (src_offset_d < src_offset_i) rem = (double)src_offset_i - src_offset_d;
517  }
518 }
519 
520 
524 void sample_move_d16_d16(int16_t *dst, int16_t *src,
525  uint64_t nsamples, size_t tbytes, double scale, int nDstChannels,
526  int nSrcChannels, int swap_endian, int swap_sign) {
527  // TODO: going from >1 channels to 1, we should average
528  static double rem = 0.f;
529  double src_offset_d = rem;
530  int16_t *ptr;
531  int16_t *src_end;
532  int nSrcCount, nDstCount;
533  off_t src_offset_i = 0;
534  int ccount = 0;
535 
536  if (!nSrcChannels) return;
537 
538  if (scale < 0.f) {
539  src_offset_d = ((double)nsamples * (-scale) - 1.f - rem);
540  src_offset_i = (off_t)src_offset_d * nSrcChannels;
541  }
542 
543  // take care of rounding errors
544  src_end = src + tbytes / 2 - nSrcChannels;
545 
546  if ((off_t)((fabs(scale) * (double)nsamples) + rem) * nSrcChannels * 2 > tbytes)
547  scale = scale > 0. ? ((double)(tbytes / nSrcChannels / 2) - rem) / (double)nsamples
548  : -(((double)(tbytes / nSrcChannels / 2) - rem) / (double)nsamples);
549 
550  while (nsamples--) {
551  if ((nSrcCount = nSrcChannels) == (nDstCount = nDstChannels) && !swap_endian && !swap_sign) {
552  // same number of channels
553 
554  if (scale == 1.f) {
555  lives_memcpy((void *)dst, (void *)src, nsamples * 2 * nSrcChannels);
556  return;
557  }
558 
559  ptr = src + src_offset_i;
560  ptr = ptr > src ? (ptr < src_end ? ptr : src_end) : src;
561  lives_memcpy(dst, ptr, nSrcChannels * 2);
562  dst += nDstCount;
563  } else {
564  ccount = 0;
565 
566  /* loop until all of our destination channels are filled */
567  while (nDstCount) {
568  nSrcCount--;
569  nDstCount--;
570 
571  ptr = src + ccount + src_offset_i;
572  ptr = ptr > src ? (ptr < (src_end + ccount) ? ptr : (src_end + ccount)) : src;
573 
574  /* copy the data over */
575  if (!swap_endian) {
576  if (!swap_sign) *(dst++) = *ptr;
577  else if (swap_sign == SWAP_S_TO_U) *((uint16_t *)dst++) = (uint16_t)(*ptr + SAMPLE_MAX_16BITI);
578  else *(dst++) = *ptr - SAMPLE_MAX_16BITI;
579  } else if (swap_endian == SWAP_X_TO_L) {
580  if (!swap_sign) *(dst++) = (((*ptr) & 0x00FF) << 8) + ((*ptr) >> 8);
581  else if (swap_sign == SWAP_S_TO_U) *((uint16_t *)dst++) = (uint16_t)(((*ptr & 0x00FF) << 8) + (*ptr >> 8)
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 
617 void sample_move_d16_d8(uint8_t *dst, short *src,
618  uint64_t nsamples, size_t tbytes, double scale, int nDstChannels, int nSrcChannels, int swap_sign) {
619  // TODO: going from >1 channels to 1, we should average
620  double rem = 0.f;
621  double src_offset_d = rem;
622  short *ptr;
623  short *src_end;
624  off_t src_offset_i = 0;
625  int ccount = 0;
626  int nSrcCount, nDstCount;
627 
628  if (!nSrcChannels) return;
629 
630  if (scale < 0.f) {
631  src_offset_d = ((double)nsamples * (-scale) - 1.f - rem);
632  src_offset_i = (off_t)src_offset_d * nSrcChannels;
633  }
634 
635  src_end = src + tbytes / sizeof(short) - nSrcChannels;
636 
637  while (nsamples--) {
638  nSrcCount = nSrcChannels;
639  nDstCount = nDstChannels;
640 
641  ccount = 0;
642 
643  /* loop until all of our destination channels are filled */
644  while (nDstCount) {
645  nSrcCount--;
646  nDstCount--;
647 
648  ptr = src + ccount + src_offset_i;
649  ptr = ptr > src ? (ptr < (src_end + ccount) ? ptr : src_end + ccount) : src;
650 
651  /* copy the data over */
652  if (!swap_sign) *(dst++) = (*ptr >> 8);
653  else if (swap_sign == SWAP_S_TO_U) *(dst++) = (uint8_t)((int8_t)(*ptr >> 8) + 128);
654  else *((int8_t *)dst++) = (int8_t)((uint8_t)(*ptr >> 8) - 128);
655  ccount++;
656 
657  /* if we ran out of source channels but not destination channels */
658  /* then start the src channels back where we were */
659  if (!nSrcCount && nDstCount) {
660  ccount = 0;
661  nSrcCount = nSrcChannels;
662  }
663  }
664 
665  /* advance the position */
666  src_offset_i = (off_t)((src_offset_d += scale) + .4999) * nSrcChannels;
667  }
668  rem = 0.f;
669  if (scale > 0.f) {
670  if (src_offset_d > src_offset_i) rem = src_offset_d - (double)src_offset_i;
671  } else {
672  if (src_offset_d < src_offset_i) rem = (double)src_offset_i - src_offset_d;
673  }
674 }
675 
676 
677 float sample_move_d16_float(float *dst, short *src, uint64_t nsamples, uint64_t src_skip, int is_unsigned, boolean rev_endian,
678  float vol) {
679  // convert 16 bit audio to float audio
680 
681  // returns abs(maxvol heard)
682 
683  float svolp, svoln;
684 
685 #ifdef ENABLE_OIL
686  float val = 0.; // set a value to stop valgrind complaining
687  float maxval = 0.;
688  double xn, xp, xa;
689  double y = 0.f;
690 #else
691  float val;
692  float maxval = 0.;
693  short valss;
694 #endif
695 
696  uint8_t srcx[2];
697  short srcxs;
698  short *srcp;
699 
700  if (vol == 0.) vol = 0.0000001f;
701  svolp = SAMPLE_MAX_16BIT_P / vol;
702  svoln = SAMPLE_MAX_16BIT_N / vol;
703 
704 #ifdef ENABLE_OIL
705  xp = 1. / svolp;
706  xn = 1. / svoln;
707  xa = 2. * vol / (SAMPLE_MAX_16BIT_P + SAMPLE_MAX_16BIT_N);
708 #endif
709 
710  while (nsamples--) { // valgrind
711  if (rev_endian) {
712  lives_memcpy(&srcx, src, 2);
713  srcxs = ((srcx[1] & 0xFF) << 8) + (srcx[0] & 0xFF);
714  srcp = &srcxs;
715  } else srcp = src;
716 
717  if (!is_unsigned) {
718 #ifdef ENABLE_OIL
719  oil_scaleconv_f32_s16(&val, srcp, 1, &y, val > 0 ? &xp : &xn);
720 #else
721  if ((val = (float)((float)(*srcp) / (*srcp > 0 ? svolp : svoln))) > 1.0f) val = 1.0f;
722  else if (val < -1.0f) val = -1.0f;
723 #endif
724  } else {
725 #ifdef ENABLE_OIL
726  oil_scaleconv_f32_u16(&val, (unsigned short *)srcp, 1, &y, &xa);
727  val -= vol;
728 #else
729  valss = (unsigned short) * srcp - SAMPLE_MAX_16BITI;
730  if ((val = (float)((float)(valss) / (valss > 0 ? svolp : svoln))) > 1.0f) val = 1.0f;
731  else if (val < -1.0f) val = -1.0f;
732 #endif
733  }
734 
735  if (val > maxval) maxval = val;
736  else if (-val > maxval) maxval = -val;
737 
738  *(dst++) = val;
739  src += src_skip;
740  }
741  return maxval;
742 }
743 
744 
745 void sample_move_float_float(float *dst, float *src, uint64_t nsamples, double scale, int dst_skip) {
746  // copy one channel of float to a buffer, applying the scale (scale 2.0 to double the rate, etc)
747  static double rem = 0.f;
748  double offs_d = rem;
749  off_t offs = 0;
750  int i;
751 
752  if (scale < 0.f) {
753  offs_d = ((double)nsamples * (-scale) - 1.f - rem);
754  offs = (off_t)offs_d;
755  }
756 
757  if (scale == 1.f && dst_skip == 1) {
758  lives_memcpy((void *)dst, (void *)src, nsamples * sizeof(float));
759  return;
760  }
761 
762  for (i = 0; i < nsamples; i++) {
763  *dst = src[offs];
764  dst += dst_skip;
765  offs = (off_t)((offs_d += scale) + .4999);
766  }
767  rem = 0.f;
768  if (scale > 0.f) {
769  if (offs_d > offs) rem = offs_d - (double)offs;
770  } else {
771  if (offs_d < offs) rem = (double)offs - offs_d;
772  }
773 }
774 
775 
776 #define CLIP_DECAY ((double)16535. / (double)16536.)
777 
793 int64_t sample_move_float_int(void *holding_buff, float **float_buffer, int nsamps, double scale, int chans, int asamps,
794  int usigned, boolean rev_endian, boolean interleaved, float vol) {
795  int64_t frames_out = 0l;
796  int i;
797  off_t offs = 0, coffs = 0, lcoffs = -1;
798 
799  static double coffs_d = 0.f;
800  const double add = (1.0 - CLIP_DECAY);
801 
802  short *hbuffs = (short *)holding_buff;
803  unsigned short *hbuffu = (unsigned short *)holding_buff;
804  unsigned char *hbuffc = (unsigned char *)holding_buff;
805  short val[chans];
806  unsigned short valu[chans];
807  static float clip = 1.0;
808  float ovalf[chans], valf[chans], fval;
809  float volx = vol, ovolx = -1.;
810  boolean checklim = FALSE;
811 
812  asamps >>= 3;
813 
814  if (clip > 1.0) checklim = TRUE;
815 
816  while ((nsamps - frames_out) > 0) {
817  frames_out++;
818  if (checklim) {
819  if (clip > 1.0) {
820  clip = clip * CLIP_DECAY + add;
821  volx = vol / clip;
822  } else {
823  checklim = FALSE;
824  clip = 1.0;
825  volx = vol;
826  }
827  }
828 
829  for (i = 0; i < chans; i++) {
830  if (coffs != lcoffs) {
831  if ((fval = fabsf((ovalf[i] = *(float_buffer[i] + (interleaved ? (coffs * chans) : coffs))))) > clip) {
832  clip = fval;
833  checklim = TRUE;
834  volx = (vol / clip);
835  i = -1;
836  continue;
837  }
838  }
839  if (volx != ovolx || coffs != lcoffs) {
840  valf[i] = ovalf[i] * volx;
841  if (valf[i] > vol) valf[i] = vol;
842  else if (valf[i] < -vol) valf[i] = -vol;
843  ovolx = volx;
844  val[i] = (short)(valf[i] * (valf[i] > 0. ? SAMPLE_MAX_16BIT_P : SAMPLE_MAX_16BIT_N));
845  if (usigned) valu[i] = (val[i] + SAMPLE_MAX_16BITI);
846  }
847 
848  if (asamps == 2) {
849  if (!rev_endian) {
850  if (usigned) *(hbuffu + offs) = valu[i];
851  else *(hbuffs + offs) = val[i];
852  } else {
853  if (usigned) {
854  *(hbuffc + offs) = valu[i] & 0x00FF;
855  *(hbuffc + (++offs)) = (valu[i] & 0xFF00) >> 8;
856  } else {
857  *(hbuffc + offs) = val[i] & 0x00FF;
858  *(hbuffc + (++offs)) = (val[i] & 0xFF00) >> 8;
859  }
860  }
861  } else {
862  *(hbuffc + offs) = (unsigned char)(valu[i] >> 8);
863  }
864  offs++;
865  }
866  lcoffs = coffs;
867  coffs = (off_t)((coffs_d += scale) + .4999);
868  }
869  coffs_d -= (double)coffs;
870  if (prefs->show_dev_opts) {
871  if (frames_out != nsamps) {
872  char *msg = lives_strdup_printf("audio float -> int: buffer mismatch of %ld samples\n", frames_out - nsamps);
873  LIVES_WARN(msg);
874  lives_free(msg);
875  }
876  }
877  return frames_out;
878 }
879 
880 
881 // play from memory buffer
882 
888 int64_t sample_move_abuf_float(float **obuf, int nchans, int nsamps, int out_arate, float vol) {
889  int samples_out = 0;
890 
891 #ifdef ENABLE_JACK
892 
893  int samps = 0;
894 
895  lives_audio_buf_t *abuf;
896  int in_arate;
897  off_t offs = 0, ioffs, xchan;
898 
899  double src_offset_d = 0.f;
900  off_t src_offset_i = 0;
901 
902  int i, j;
903 
904  double scale;
905 
906  size_t curval;
907 
908  pthread_mutex_lock(&mainw->abuf_mutex);
909  if (mainw->jackd->read_abuf == -1) {
910  pthread_mutex_unlock(&mainw->abuf_mutex);
911  return 0;
912  }
913  abuf = mainw->jackd->abufs[mainw->jackd->read_abuf];
914  in_arate = abuf->arate;
915  pthread_mutex_unlock(&mainw->abuf_mutex);
916  scale = (double)in_arate / (double)out_arate;
917 
918  while (nsamps > 0) {
919  pthread_mutex_lock(&mainw->abuf_mutex);
920  if (mainw->jackd->read_abuf == -1) {
921  pthread_mutex_unlock(&mainw->abuf_mutex);
922  return 0;
923  }
924 
925  ioffs = abuf->start_sample;
926  pthread_mutex_unlock(&mainw->abuf_mutex);
927  samps = 0;
928 
929  src_offset_i = 0;
930  src_offset_d = 0.;
931 
932  for (i = 0; i < nsamps; i++) {
933  // process each sample
934 
935  if ((curval = ioffs + src_offset_i) >= abuf->samples_filled) {
936  // current buffer is consumed
937  break;
938  }
939  xchan = 0;
940  for (j = 0; j < nchans; j++) {
941  // copy channel by channel (de-interleave)
942  pthread_mutex_lock(&mainw->abuf_mutex);
943  if (mainw->jackd->read_abuf < 0) {
944  pthread_mutex_unlock(&mainw->abuf_mutex);
945  return samples_out;
946  }
947  if (xchan >= abuf->out_achans) xchan = 0;
948  obuf[j][offs + i] = abuf->bufferf[xchan][curval] * vol;
949  pthread_mutex_unlock(&mainw->abuf_mutex);
950  xchan++;
951  }
952  // resample on the fly
953  src_offset_i = (off_t)((src_offset_d += scale) + .4999);
954  samps++;
955  samples_out++;
956  }
957 
958  abuf->start_sample = ioffs + src_offset_i;
959  nsamps -= samps;
960  offs += samps;
961 
962  if (nsamps > 0) {
963  // buffer was consumed, move on to next buffer
964  pthread_mutex_lock(&mainw->abuf_mutex);
965  // request caching thread to fill another buffer
966  mainw->abufs_to_fill++;
967  if (mainw->jackd->read_abuf < 0) {
968  // playback ended while we were processing
969  pthread_mutex_unlock(&mainw->abuf_mutex);
970  return samples_out;
971  }
972  mainw->jackd->read_abuf++;
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 
993 int64_t sample_move_abuf_int16(short *obuf, int nchans, int nsamps, int out_arate) {
994  int samples_out = 0;
995 
996 #ifdef HAVE_PULSE_AUDIO
997 
998  int samps = 0;
999 
1000  lives_audio_buf_t *abuf;
1001  int in_arate, nsampsx;
1002  ssize_t offs = 0, ioffs, xchan;
1003 
1004  double src_offset_d = 0.f;
1005  ssize_t src_offset_i = 0;
1006 
1007  int i, j;
1008 
1009  double scale;
1010  ssize_t curval;
1011 
1012  pthread_mutex_lock(&mainw->abuf_mutex);
1013  if (mainw->pulsed->read_abuf == -1) {
1014  pthread_mutex_unlock(&mainw->abuf_mutex);
1015  return 0;
1016  }
1017 
1018  abuf = mainw->pulsed->abufs[mainw->pulsed->read_abuf];
1019  in_arate = abuf->arate;
1020  pthread_mutex_unlock(&mainw->abuf_mutex);
1021  scale = (double)in_arate / (double)out_arate;
1022 
1023  while (nsamps > 0) {
1024  pthread_mutex_lock(&mainw->abuf_mutex);
1025  if (mainw->pulsed->read_abuf == -1) {
1026  pthread_mutex_unlock(&mainw->abuf_mutex);
1027  return 0;
1028  }
1029 
1030  ioffs = abuf->start_sample;
1031  pthread_mutex_unlock(&mainw->abuf_mutex);
1032  samps = 0;
1033 
1034  src_offset_i = 0;
1035  src_offset_d = 0.;
1036  nsampsx = nsamps * nchans;
1037 
1038  for (i = 0; i < nsampsx; i += nchans) {
1039  // process each sample
1040 
1041  if ((curval = ioffs + src_offset_i) >= abuf->samples_filled) {
1042  // current buffer is drained
1043  break;
1044  }
1045  xchan = 0;
1046  curval *= abuf->out_achans;
1047  for (j = 0; j < nchans; j++) {
1048  pthread_mutex_lock(&mainw->abuf_mutex);
1049  if (mainw->pulsed->read_abuf < 0) {
1050  pthread_mutex_unlock(&mainw->abuf_mutex);
1051  return samps;
1052  }
1053  if (xchan >= abuf->out_achans) xchan = 0;
1054  obuf[(offs++)] = abuf->buffer16[0][curval + xchan];
1055  pthread_mutex_unlock(&mainw->abuf_mutex);
1056  xchan++;
1057  }
1058  src_offset_i = (ssize_t)((src_offset_d += scale) + .4999);
1059  samps++;
1060  }
1061 
1062  abuf->start_sample = ioffs + src_offset_i;
1063  nsamps -= samps;
1064  samples_out += samps;
1065 
1066  if (nsamps > 0) {
1067  // buffer was drained, move on to next buffer
1068  pthread_mutex_lock(&mainw->abuf_mutex);
1069  // request main thread to fill another buffer
1070  mainw->abufs_to_fill++;
1071 
1072  if (mainw->pulsed->read_abuf < 0) {
1073  // playback ended while we were processing
1074  pthread_mutex_unlock(&mainw->abuf_mutex);
1075  return samples_out;
1076  }
1077 
1078  mainw->pulsed->read_abuf++;
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 
1095 static size_t chunk_to_float_abuf(lives_audio_buf_t *abuf, float **float_buffer, int nsamps) {
1096  int chans = abuf->out_achans;
1097  size_t offs = abuf->samples_filled;
1098  int i;
1099 
1100  for (i = 0; i < chans; i++) {
1101  lives_memcpy(&(abuf->bufferf[i][offs]), float_buffer[i], nsamps * sizeof(float));
1102  }
1103  return (size_t)nsamps;
1104 }
1105 
1106 
1107 boolean float_deinterleave(float *fbuffer, int nsamps, int nchans) {
1108  // deinterleave a float buffer
1109  int i, j;
1110 
1111  float *tmpfbuffer = (float *)lives_calloc_safety(nsamps * nchans, sizeof(float));
1112  if (!tmpfbuffer) return FALSE;
1113 
1114  for (i = 0; i < nsamps; i++) {
1115  for (j = 0; j < nchans; j++) {
1116  tmpfbuffer[nsamps * j + i] = fbuffer[i * nchans + j];
1117  }
1118  }
1119  lives_memcpy(fbuffer, tmpfbuffer, nsamps * nchans * sizeof(float));
1120  lives_free(tmpfbuffer);
1121  return TRUE;
1122 }
1123 
1124 
1125 boolean float_interleave(float *fbuffer, int nsamps, int nchans) {
1126  // deinterleave a float buffer
1127  int i, j;
1128 
1129  float *tmpfbuffer = (float *)lives_calloc_safety(nsamps * nchans, sizeof(float));
1130  if (!tmpfbuffer) return FALSE;
1131 
1132  for (i = 0; i < nsamps; i++) {
1133  for (j = 0; j < nchans; j++) {
1134  tmpfbuffer[i * nchans + j] = fbuffer[j * nsamps + i];
1135  }
1136  }
1137  lives_memcpy(fbuffer, tmpfbuffer, nsamps * nchans * sizeof(float));
1138  lives_free(tmpfbuffer);
1139  return TRUE;
1140 }
1141 
1142 
1143 // for pulse audio we use S16LE interleaved, and the volume is adjusted later
1144 
1145 static size_t chunk_to_int16_abuf(lives_audio_buf_t *abuf, float **float_buffer, int nsamps) {
1146  int64_t frames_out;
1147  int chans = abuf->out_achans;
1148  size_t offs = abuf->samples_filled * chans;
1149 
1150  frames_out = sample_move_float_int(abuf->buffer16[0] + offs, float_buffer, nsamps, 1., chans, 16,
1151  0, 0, 0, 1.0);
1152 
1153  return (size_t)frames_out;
1154 }
1155 
1156 
1157 //#define DEBUG_ARENDER
1158 
1159 boolean pad_with_silence(int out_fd, void *buff, off64_t oins_size, int64_t ins_size, int asamps, int aunsigned,
1160  boolean big_endian) {
1161  // asamps is sample size in BYTES
1162  // fill to ins_pt with zeros (or 0x80.. for unsigned)
1163  // oins_size is the current file length, ins_size is the point where we want append to (both in bytes)
1164  // if ins size < oins_size we just seek to ins_size
1165  // otherwise we pad from oins_size to ins_size
1166 
1167  static uint64_t *zero_buff = NULL;
1168  static int oasamps = 0;
1169  static int ounsigned = 0;
1170  static int orevendian = 0;
1171  size_t sbytes;
1172  size_t sblocksize = SILENCE_BLOCK_SIZE;
1173  int i;
1174 
1175  boolean retval = TRUE;
1176  boolean revendian = FALSE;
1177 
1178  //#define DEBUG_ARENDER
1179 
1180  if (ins_size <= oins_size) {
1181 #ifdef DEBUG_ARENDER
1182  g_print("sbytes is l.t zero\n");
1183 #endif
1184  return FALSE;
1185  }
1186  sbytes = ins_size - oins_size;
1187 
1188 #ifdef DEBUG_ARENDER
1189  g_print("sbytes is %ld\n", sbytes);
1190 #endif
1191  if (sbytes > 0) {
1192  if ((big_endian && capable->byte_order == LIVES_LITTLE_ENDIAN)
1193  || (!big_endian && capable->byte_order == LIVES_LITTLE_ENDIAN)) revendian = TRUE;
1194  if (out_fd >= 0) lives_lseek_buffered_writer(out_fd, oins_size);
1195  else {
1196  if (!buff) return FALSE;
1197  buff += oins_size;
1198  }
1199  if (zero_buff) {
1200  if (ounsigned != aunsigned || oasamps != asamps || orevendian != revendian) {
1201  lives_free(zero_buff);
1202  zero_buff = NULL;
1203  }
1204  }
1205  if (!zero_buff) {
1206  sblocksize >>= 3;
1207  zero_buff = (uint64_t *)lives_calloc_safety(sblocksize, 8);
1208  if (aunsigned) {
1209  if (asamps > 1) {
1210  uint64_t theval = (revendian ? 0x0080008000800080ul : 0x8000800080008000ul);
1211  for (i = 0; i < sblocksize; i ++) {
1212  zero_buff[i] = theval;
1213  }
1214  } else lives_memset(zero_buff, 0x80, SILENCE_BLOCK_SIZE);
1215  }
1216  sblocksize <<= 3;
1217  ounsigned = aunsigned;
1218  oasamps = asamps;
1219  orevendian = revendian;
1220  }
1221  for (i = 0; i < sbytes; i += SILENCE_BLOCK_SIZE) {
1222  if (sbytes - i < SILENCE_BLOCK_SIZE) sblocksize = sbytes - i;
1223  if (out_fd >= 0) {
1224  lives_write_buffered(out_fd, (const char *)zero_buff, sblocksize, TRUE);
1225  if (THREADVAR(write_failed) == out_fd + 1) {
1226  THREADVAR(write_failed) = 0;
1227  retval = FALSE;
1228  }
1229  } else {
1230  lives_memcpy(buff, zero_buff, sblocksize);
1231  buff += sblocksize;
1232  }
1233  }
1234  } else if (out_fd >= 0) {
1235  lives_lseek_buffered_writer(out_fd, ins_size);
1236  }
1237  return retval;
1238 }
1239 
1240 
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
1276 int64_t render_audio_segment(int nfiles, int *from_files, int to_file, double *avels, double *fromtime,
1277  weed_timecode_t tc_start, weed_timecode_t tc_end, double *chvol, double opvol_start,
1278  double opvol_end, lives_audio_buf_t *obuf) {
1279 
1280  // TODO - allow MAX_AUDIO_MEM to be configurable; currently this is fixed at 8 MB
1281  // 16 or 32 may be a more sensible default for realtime previewing
1282  // return (audio) frames rendered
1283 
1284  weed_plant_t *shortcut = NULL;
1285  lives_clip_t *outfile = to_file > -1 ? mainw->files[to_file] : NULL;
1286  uint8_t *in_buff;
1287  void *finish_buff = NULL;
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 
1813 void aud_fade(int fileno, double startt, double endt, double startv, double endv) {
1814  double vel = 1., vol = 1.;
1815 
1816  render_audio_segment(1, &fileno, fileno, &vel, &startt, (weed_timecode_t)(startt * TICKS_PER_SECOND_DBL),
1817  (weed_timecode_t)(endt * TICKS_PER_SECOND_DBL), &vol, startv, endv, NULL);
1818 
1819  if (THREADVAR(write_failed)) {
1820  char *outfilename = lives_get_audio_file_name(fileno);
1821  THREADVAR(write_failed) = 0;
1822  do_write_failed_error_s(outfilename, NULL);
1823  lives_free(outfilename);
1824  }
1825 
1826  if (THREADVAR(read_failed)) {
1827  char *infilename = lives_get_audio_file_name(fileno);
1828  THREADVAR(read_failed) = 0;
1829  do_read_failed_error_s(infilename, NULL);
1830  lives_free(infilename);
1831  }
1832 }
1833 
1834 
1835 void preview_audio(void) {
1836  // start a minimalistic player with only audio
1837  mainw->play_start = cfile->start;
1838  mainw->play_end = cfile->end;
1839  mainw->playing_sel = TRUE;
1840 
1841  if (cfile->achans > 0) {
1842  cfile->aseek_pos = (off64_t)(cfile->real_pointer_time * cfile->arate) * cfile->achans * (cfile->asampsize / 8);
1843  if (mainw->playing_sel) {
1844  off64_t apos = (off64_t)((double)(mainw->play_start - 1.) / cfile->fps * cfile->arate) * cfile->achans *
1845  (cfile->asampsize / 8);
1846  if (apos > cfile->aseek_pos) cfile->aseek_pos = apos;
1847  }
1848  if (cfile->aseek_pos > cfile->afilesize) cfile->aseek_pos = 0.;
1849  if (mainw->current_file == 0 && cfile->arate < 0) cfile->aseek_pos = cfile->afilesize;
1850  }
1851  // start up our audio player (jack or pulse)
1852 #ifdef ENABLE_JACK
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 
1924  mainw->playing_sel = FALSE;
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 
1991 void preview_aud_vol(void) {
1992  float ovol = cfile->vol;
1993  cfile->vol = (float)mainw->fx1_val;
1994  preview_audio();
1995  cfile->vol = ovol;
1997  mainw->error = FALSE;
1998 }
1999 
2000 
2001 boolean adjust_clip_volume(int fileno, float newvol, boolean make_backup) {
2002  double dvol = (double)newvol;
2003  if (make_backup) {
2004  char *com = lives_strdup_printf("%s backup_audio \"%s\"", prefs->backend_sync, cfile->handle);
2005  lives_system(com, FALSE);
2006  lives_free(com);
2007  if (THREADVAR(com_failed)) {
2008  THREADVAR(com_failed) = FALSE;
2009  return FALSE;
2010  }
2011  }
2012  aud_fade(fileno, 0., CLIP_AUDIO_TIME(fileno), dvol, dvol);
2013  return TRUE;
2014 }
2015 
2016 
2017 #ifdef ENABLE_JACK
2018 void jack_rec_audio_to_clip(int fileno, int old_file, lives_rec_audio_type_t rec_type) {
2019  // open audio file for writing
2020  lives_clip_t *outfile;
2021 
2022  boolean jackd_read_started = (mainw->jackd_read != NULL);
2023 
2024  int retval;
2025 
2026  // should we set is_paused ? (yes)
2027  // should we reset time (no)
2028 
2029  if (fileno == -1) {
2030  // respond to external audio, but do not record it (yet)
2031  if (!mainw->jackd_read) {
2032  mainw->jackd_read = jack_get_driver(0, FALSE);
2033  mainw->jackd_read->playing_file = fileno;
2034  mainw->jackd_read->reverse_endian = FALSE;
2035  mainw->jackd_read->frames_written = 0;
2036 
2037  // start jack "recording"
2038  jack_create_client_reader(mainw->jackd_read);
2039  jack_read_driver_activate(mainw->jackd_read, FALSE);
2040  }
2041  return;
2042  }
2043 
2044  outfile = mainw->files[fileno];
2045 
2046  if (mainw->aud_rec_fd == -1) {
2047  char *outfilename = lives_get_audio_file_name(fileno);
2048  do {
2049  retval = 0;
2050  mainw->aud_rec_fd = lives_open3(outfilename, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
2051  if (mainw->aud_rec_fd < 0) {
2052  retval = do_write_failed_error_s_with_retry(outfilename, lives_strerror(errno));
2053  if (retval == LIVES_RESPONSE_CANCEL) {
2054  lives_free(outfilename);
2055  return;
2056  }
2057  }
2058  } while (retval == LIVES_RESPONSE_RETRY);
2059  lives_free(outfilename);
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 
2155 void jack_rec_audio_end(boolean close_device, boolean close_fd) {
2156  // recording ended
2157 
2158  pthread_mutex_lock(&mainw->audio_filewriteend_mutex);
2159  if (mainw->jackd_read->playing_file > -1)
2160  jack_flush_read_data(0, NULL);
2161 
2162  if (close_device) {
2163  // stop recording
2164  if (mainw->jackd_read) jack_close_device(mainw->jackd_read);
2165  mainw->jackd_read = NULL;
2166  } else {
2167  mainw->jackd_read->in_use = FALSE;
2168  mainw->jackd_read->playing_file = -1;
2169  }
2170  pthread_mutex_unlock(&mainw->audio_filewriteend_mutex);
2171 
2172  if (close_fd && mainw->aud_rec_fd != -1) {
2173  // close file
2174  close(mainw->aud_rec_fd);
2175  mainw->aud_rec_fd = -1;
2176  }
2177 }
2178 #endif
2179 
2180 
2181 #ifdef HAVE_PULSE_AUDIO
2182 
2183 void pulse_rec_audio_to_clip(int fileno, int old_file, lives_rec_audio_type_t rec_type) {
2184  // open audio file for writing
2185  lives_clip_t *outfile;
2186  int retval;
2187 
2188  if (fileno == -1) {
2189  if (!mainw->pulsed_read) {
2190  mainw->pulsed_read = pulse_get_driver(FALSE);
2191  mainw->pulsed_read->playing_file = -1;
2192  mainw->pulsed_read->frames_written = 0;
2193  mainw->pulsed_read->reverse_endian = FALSE;
2194  mainw->aud_rec_fd = -1;
2195  pulse_driver_activate(mainw->pulsed_read);
2196  }
2197  return;
2198  }
2199 
2200  outfile = mainw->files[fileno];
2201 
2202  if (mainw->aud_rec_fd == -1) {
2203  char *outfilename = lives_get_audio_file_name(fileno);
2204  do {
2205  retval = 0;
2206  mainw->aud_rec_fd = lives_open3(outfilename, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
2207  if (mainw->aud_rec_fd < 0) {
2208  retval = do_write_failed_error_s_with_retry(outfilename, lives_strerror(errno));
2209  if (retval == LIVES_RESPONSE_CANCEL) {
2210  lives_free(outfilename);
2211  return;
2212  }
2213  }
2214  } while (retval == LIVES_RESPONSE_RETRY);
2215  lives_free(outfilename);
2216  if (fileno == mainw->ascrap_file) {
2218  /* if (mainw->pulsed_read) {
2219  // flush all data from buffer; this seems like the only way
2220  void *data;
2221  size_t rbytes;
2222  pa_mloop_lock();
2223  do {
2224  pa_stream_peek(mainw->pulsed_read->pstream, (const void **)&data, &rbytes);
2225  if (rbytes > 0) pa_stream_drop(mainw->pulsed_read->pstream);
2226  } while (rbytes > 0);
2227  pa_mloop_unlock();
2228  }*/
2229  }
2230  }
2231 
2232  if (rec_type == RECA_GENERATED) {
2233  mainw->pulsed->playing_file = fileno;
2234  } else {
2235  mainw->pulsed_read = pulse_get_driver(FALSE);
2236  mainw->pulsed_read->playing_file = fileno;
2237  mainw->pulsed_read->frames_written = 0;
2238  }
2239 
2240  if (rec_type == RECA_EXTERNAL || rec_type == RECA_GENERATED) {
2241  int asigned;
2242  int aendian;
2243  off_t fsize = get_file_size(mainw->aud_rec_fd);
2244 
2245  if (rec_type == RECA_EXTERNAL) {
2246  mainw->pulsed_read->reverse_endian = FALSE;
2247 
2248  pulse_driver_activate(mainw->pulsed_read);
2249 
2250  outfile->arate = outfile->arps = mainw->pulsed_read->out_arate;
2251  outfile->achans = mainw->pulsed_read->out_achans;
2252  outfile->asampsize = mainw->pulsed_read->out_asamps;
2253  outfile->signed_endian = get_signed_endian(mainw->pulsed_read->out_signed != AFORM_UNSIGNED,
2254  mainw->pulsed_read->out_endian != AFORM_BIG_ENDIAN);
2255 
2256  asigned = !(outfile->signed_endian & AFORM_UNSIGNED);
2257  aendian = !(outfile->signed_endian & AFORM_BIG_ENDIAN);
2258 
2259  mainw->pulsed_read->frames_written = fsize / (outfile->achans * (outfile->asampsize >> 3));
2260  } else {
2261  mainw->pulsed->reverse_endian = FALSE;
2262  outfile->arate = outfile->arps = mainw->pulsed->out_arate;
2263  outfile->achans = mainw->pulsed->out_achans;
2264  outfile->asampsize = mainw->pulsed->out_asamps;
2265  outfile->signed_endian = get_signed_endian(mainw->pulsed->out_signed != AFORM_UNSIGNED,
2266  mainw->pulsed->out_endian != AFORM_BIG_ENDIAN);
2267 
2268  asigned = !(outfile->signed_endian & AFORM_UNSIGNED);
2269  aendian = !(outfile->signed_endian & AFORM_BIG_ENDIAN);
2270  }
2271 
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 
2317 void pulse_rec_audio_end(boolean close_device, boolean close_fd) {
2318  // recording ended
2319 
2320  // stop recording
2321 
2322  if (mainw->pulsed_read) {
2323  pthread_mutex_lock(&mainw->audio_filewriteend_mutex);
2324  if (mainw->pulsed_read->playing_file > -1)
2325  pulse_flush_read_data(mainw->pulsed_read, mainw->pulsed_read->playing_file, 0, mainw->pulsed_read->reverse_endian, NULL);
2326 
2327  if (close_device) pulse_close_client(mainw->pulsed_read);
2328 
2329  if (close_device) mainw->pulsed_read = NULL;
2330  else {
2331  mainw->pulsed_read->in_use = FALSE;
2332  mainw->pulsed_read->playing_file = -1;
2333  }
2334  pthread_mutex_unlock(&mainw->audio_filewriteend_mutex);
2335  }
2336 
2337  if (mainw->aud_rec_fd != -1 && close_fd) {
2338  // close file
2339  close(mainw->aud_rec_fd);
2340  mainw->aud_rec_fd = -1;
2341  }
2342 }
2343 
2344 #endif
2345 
2347 
2348 // playback via memory buffers (e.g. in multitrack)
2349 
2352 
2353 static lives_audio_track_state_t *resize_audstate(lives_audio_track_state_t *ostate, int nostate, int nstate) {
2354  // increase the element size of the audstate array (ostate)
2355  // from nostate elements to nstate elements
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 
2365 static lives_audio_track_state_t *aframe_to_atstate_inner(weed_plant_t *event, int *ntracks) {
2366  // parse an audio frame, and set the track file, seek and velocity values
2367  int num_aclips = 0, atrack;
2368  int *aclips = NULL;
2369  double *aseeks = NULL;
2370  int naudstate = 0;
2371  lives_audio_track_state_t *atstate = NULL;
2372 
2373  int i;
2374 
2375  int btoffs = mainw->multitrack ? mainw->multitrack->opts.back_audio_tracks : 1;
2376  num_aclips = weed_frame_event_get_audio_tracks(event, &aclips, &aseeks);
2377  for (i = 0; i < num_aclips; i += 2) {
2378  if (aclips[i + 1] > 0) { // else ignore
2379  atrack = aclips[i];
2380  if (atrack + btoffs >= naudstate - 1) {
2381  atstate = resize_audstate(atstate, naudstate, atrack + btoffs + 2);
2382  naudstate = atrack + btoffs + 1;
2383  atstate[naudstate].afile = -1;
2384  }
2385  atstate[atrack + btoffs].afile = aclips[i + 1];
2386  atstate[atrack + btoffs].seek = aseeks[i];
2387  atstate[atrack + btoffs].vel = aseeks[i + 1];
2388  }
2389  }
2390 
2391  lives_freep((void **)&aclips);
2392  lives_freep((void **)&aseeks);
2393 
2394  if (ntracks) *ntracks = num_aclips;
2395 
2396  return atstate;
2397 }
2398 
2399 
2401  return aframe_to_atstate_inner(event, NULL);
2402 }
2403 
2404 
2406  return aframe_to_atstate_inner(event, ntracks);
2407 }
2408 
2409 
2419 lives_audio_track_state_t *get_audio_and_effects_state_at(weed_plant_t *event_list, weed_plant_t *st_event,
2420  weed_timecode_t fill_tc, int what_to_get, boolean exact) {
2421  // if exact is set, we must rewind back to first active stateful effect,
2422  // and play forwards from there (not yet implemented - TODO)
2423  lives_audio_track_state_t *atstate = NULL, *audstate = NULL;
2424  weed_timecode_t last_tc = 0;
2425  weed_event_t *event, *nevent;
2426  weed_event_t *deinit_event;
2427  int nfiles, nnfiles, etype;
2428 
2429  // gets effects state immediately prior to start_event. (initing any effects which should be active, and applying param changes
2430  // if not in multrack)
2431 
2432  // optionally: gets audio state, sets atstate[0].tc
2433  // and initialises audio buffers
2434 
2435  if (fill_tc == 0) {
2436  if (what_to_get != LIVES_PREVIEW_TYPE_AUDIO_ONLY)
2437  mainw->filter_map = NULL;
2438  if (what_to_get != LIVES_PREVIEW_TYPE_VIDEO_ONLY)
2439  mainw->afilter_map = NULL;
2440  event = get_first_event(event_list);
2441  } else {
2442  event = st_event;
2443  st_event = NULL;
2444  }
2445 
2446  while ((st_event && event != st_event) || (!st_event && get_event_timecode(event) < fill_tc)) {
2447  etype = weed_event_get_type(event);
2448  if (what_to_get == LIVES_PREVIEW_TYPE_VIDEO_AUDIO || (etype != 1 && etype != 5)) {
2449  switch (etype) {
2450  case WEED_EVENT_TYPE_FILTER_MAP:
2451  if (what_to_get != LIVES_PREVIEW_TYPE_AUDIO_ONLY)
2452  mainw->filter_map = event;
2453  if (what_to_get != LIVES_PREVIEW_TYPE_VIDEO_ONLY) {
2454  mainw->afilter_map = event;
2455  }
2456  break;
2457  case WEED_EVENT_TYPE_FILTER_INIT:
2458  deinit_event = weed_get_plantptr_value(event, WEED_LEAF_DEINIT_EVENT, NULL);
2459  if (!deinit_event || get_event_timecode(deinit_event) >= fill_tc) {
2460  // this effect should be activated
2461  if (what_to_get != LIVES_PREVIEW_TYPE_AUDIO_ONLY)
2462  process_events(event, FALSE, get_event_timecode(event));
2463  if (what_to_get != LIVES_PREVIEW_TYPE_VIDEO_ONLY)
2464  process_events(event, TRUE, get_event_timecode(event));
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 
2567 void fill_abuffer_from(lives_audio_buf_t *abuf, weed_plant_t *event_list, weed_plant_t *st_event, boolean exact) {
2568  // fill audio buffer with audio samples, using event_list as a guide
2569  // if st_event!=NULL, that is our start event, and we will calculate the audio state at that
2570  // point
2571 
2572  // otherwise, we continue from where we left off the last time
2573 
2574  // all we really do here is set from_files, aseeks and avels arrays and call render_audio_segment
2575  // effects are ignored here; they are applied in smaller chunks in render_audio_segment, so that parameter interpolation can be done
2576 
2577  lives_audio_track_state_t *atstate = NULL;
2578  double chvols[MAX_AUDIO_TRACKS]; // TODO - use list
2579 
2580  static weed_timecode_t last_tc, tc;
2581  static weed_timecode_t fill_tc;
2582  static weed_plant_t *event;
2583  static int nfiles;
2584 
2585  static int *from_files = NULL;
2586  static double *aseeks = NULL, *avels = NULL;
2587 
2588  int i;
2589 
2590  if (!abuf) return;
2591 
2592  abuf->samples_filled = 0; // write fill level of buffer
2593  abuf->start_sample = 0; // read level
2594 
2595  if (st_event) {
2596  // this is only called for the first buffered read
2597  //
2598  event = st_event;
2599  last_tc = get_event_timecode(event);
2600 
2601  lives_freep((void **)&from_files);
2602  lives_freep((void **)&avels);
2603  lives_freep((void **)&aseeks);
2604 
2605  if (mainw->multitrack && mainw->multitrack->avol_init_event)
2606  nfiles = weed_leaf_num_elements(mainw->multitrack->avol_init_event, WEED_LEAF_IN_TRACKS);
2607 
2608  else nfiles = 1;
2609 
2610  from_files = (int *)lives_calloc(nfiles, sizint);
2611  avels = (double *)lives_calloc(nfiles, sizdbl);
2612  aseeks = (double *)lives_calloc(nfiles, sizdbl);
2613 
2614  for (i = 0; i < nfiles; i++) {
2615  from_files[i] = 0;
2616  avels[i] = aseeks[i] = 0.;
2617  }
2618 
2619  // get audio and fx state at pt immediately before st_event
2620  atstate = get_audio_and_effects_state_at(event_list, event, 0, LIVES_PREVIEW_TYPE_VIDEO_AUDIO, exact);
2621 
2622  if (atstate) {
2623  for (i = 0; atstate[i].afile != -1; i++) {
2624  if (atstate[i].afile > 0) {
2625  from_files[i] = atstate[i].afile;
2626  avels[i] = atstate[i].vel;
2627  aseeks[i] = atstate[i].seek;
2628  }
2629  }
2630  lives_free(atstate);
2631  }
2632  }
2633 
2634  if (mainw->multitrack) {
2635  // get channel volumes from the mixer
2636  for (i = 0; i < nfiles; i++) {
2637  if (mainw->multitrack && mainw->multitrack->audio_vols) {
2638  chvols[i] = (double)LIVES_POINTER_TO_INT(lives_list_nth_data(mainw->multitrack->audio_vols, i)) / ONE_MILLION_DBL;
2639  }
2640  }
2641  } else chvols[0] = 1.;
2642 
2643  fill_tc = last_tc + fabs((double)(abuf->samp_space) / (double)abuf->arate * TICKS_PER_SECOND_DBL);
2644 
2645  // continue until we have a full buffer
2646  // if we get an audio frame we render up to that point
2647  // then we render what is left to fill abuf
2648  while (event && (tc = get_event_timecode(event)) < fill_tc) {
2649  if (WEED_EVENT_IS_AUDIO_FRAME(event)) {
2650  // got next audio frame
2651  render_audio_segment(nfiles, from_files, -1, avels, aseeks, last_tc, tc, chvols, 1., 1., abuf);
2652 
2653  /* for (i = 0; i < nfiles; i++) { */
2654  /* // increase seek values */
2655  /* aseeks[i] += avels[i] * (tc - last_tc) / TICKS_PER_SECOND_DBL; */
2656  /* } */
2657 
2658  last_tc = tc;
2659  // process audio updates at this frame
2660  atstate = aframe_to_atstate(event);
2661 
2662  if (atstate) {
2663  int nnfiles;
2664  for (nnfiles = 0; atstate[nnfiles].afile != -1; nnfiles++);
2665  for (i = 0; i < nnfiles; i++) {
2666  if (atstate[i].afile > 0) {
2667  from_files[i] = atstate[i].afile;
2668  avels[i] = atstate[i].vel;
2669  aseeks[i] = atstate[i].seek;
2670  }
2671  }
2672  lives_free(atstate);
2673  }
2674  }
2675  event = get_next_audio_frame_event(event);
2676  }
2677 
2678  if (last_tc < fill_tc) {
2679  // fill the rest of the buffer
2680  /* if (nfiles == 0) */
2681  /* render_audio_segment(1, NULL, -1, NULL, NULL, last_tc, fill_tc, chvols, 0., 0., abuf); */
2682  //else
2683  render_audio_segment(nfiles, from_files, -1, avels, aseeks, last_tc, fill_tc, chvols, 1., 1., abuf);
2684  /* for (i = 0; i < nfiles; i++) { */
2685  /* // increase seek values */
2686  /* aseeks[i] += avels[i] * (fill_tc - last_tc) / TICKS_PER_SECOND_DBL; */
2687  /* } */
2688  }
2689 
2690  if (THREADVAR(read_failed) > 0) {
2691  THREADVAR(read_failed) = 0;
2692  do_read_failed_error_s(THREADVAR(read_failed_file), NULL);
2693  }
2694 
2695  mainw->write_abuf++;
2697 
2698  last_tc = fill_tc;
2699 
2700  pthread_mutex_lock(&mainw->abuf_mutex);
2701  if (mainw->abufs_to_fill > 0) {
2702  mainw->abufs_to_fill--;
2703  }
2704  pthread_mutex_unlock(&mainw->abuf_mutex);
2705 }
2706 
2707 
2708 void 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 
2729 void 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)) {
2798  mainw->force_show = TRUE;
2800  }
2801  pthread_mutex_unlock(&mainw->avseek_mutex);
2802  }
2803 #endif
2804 }
2805 
2806 
2822 boolean resync_audio(double frameno) {
2823  if (!(prefs->audio_opts & AUDIO_OPTS_FOLLOW_FPS)) return FALSE;
2824  // if recording external audio, we are intrinsically in sync
2825  if (mainw->record && prefs->audio_src == AUDIO_SRC_EXT) return TRUE;
2826 
2827  // if we are playing an audio generator or an event_list, then resync is meaningless
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 
2883 static lives_audio_buf_t *cache_buffer = NULL;
2884 static pthread_t athread;
2885 
2886 static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
2887 static pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER;
2888 
2889 
2904 static void *cache_my_audio(void *arg) {
2905  lives_audio_buf_t *cbuffer = (lives_audio_buf_t *)arg;
2906  char *filename;
2907  int i;
2908 
2909  while (!cbuffer->die) {
2910  // wait for request from client (setting cbuffer->is_ready or cbuffer->die)
2911  while (cbuffer->is_ready && !cbuffer->die && mainw->abufs_to_fill <= 0) {
2912  pthread_mutex_lock(&cond_mutex);
2913  pthread_cond_wait(&cond, &cond_mutex);
2914  pthread_mutex_unlock(&cond_mutex);
2915  }
2916 
2917  if (cbuffer->die) {
2918  if (!mainw->event_list || (mainw->record
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 
3230 void wake_audio_thread(void) {
3231  if (cache_buffer) cache_buffer->is_ready = FALSE;
3232  pthread_mutex_lock(&cond_mutex);
3233  pthread_cond_signal(&cond);
3234  pthread_mutex_unlock(&cond_mutex);
3235 }
3236 
3237 
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 
3276 void audio_cache_end(void) {
3277  lives_audio_buf_t *xcache_buffer;
3278  int i;
3279 
3280  pthread_mutex_lock(&mainw->cache_buffer_mutex);
3281  if (!cache_buffer) {
3282  pthread_mutex_unlock(&mainw->cache_buffer_mutex);
3283  return;
3284  }
3285  cache_buffer->die = TRUE;
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 
3332 boolean get_audio_from_plugin(float **fbuffer, int nchans, int arate, int nsamps, boolean is_audio_thread) {
3333  // get audio from an audio generator; fbuffer is filled with non-interleaved float
3335  weed_plant_t *orig_inst = inst;
3336  weed_plant_t *filter;
3337  weed_plant_t *channel;
3338  weed_plant_t *ctmpl;
3339  weed_timecode_t tc;
3340  weed_error_t retval;
3341  int flags, cflags;
3342  int xnchans = 0, xxnchans, xrate = 0;
3343  boolean rvary = FALSE, lvary = FALSE;
3344 
3345  if (mainw->agen_needs_reinit) {
3346  weed_instance_unref(inst);
3347  return FALSE; // wait for other thread to reinit us
3348  }
3349  tc = (double)mainw->agen_samps_count / (double)arate * TICKS_PER_SECOND_DBL;
3350  filter = weed_instance_get_filter(inst, FALSE);
3351  flags = weed_filter_get_flags(filter);
3352 
3353  if (flags & WEED_FILTER_AUDIO_RATES_MAY_VARY) rvary = TRUE;
3354  if (flags & WEED_FILTER_CHANNEL_LAYOUTS_MAY_VARY) lvary = TRUE;
3355 
3356 getaud1:
3357 
3358  channel = get_enabled_channel(inst, 0, FALSE);
3359  if (channel) {
3360  xnchans = nchans; // preferred value
3361  ctmpl = weed_channel_get_template(channel);
3362  cflags = weed_chantmpl_get_flags(ctmpl);
3363 
3364  if (lvary && weed_plant_has_leaf(ctmpl, WEED_LEAF_AUDIO_CHANNELS))
3365  xnchans = weed_get_int_value(ctmpl, WEED_LEAF_AUDIO_CHANNELS, NULL);
3366  else if (weed_plant_has_leaf(filter, WEED_LEAF_MAX_AUDIO_CHANNELS)) {
3367  xxnchans = weed_get_int_value(filter, WEED_LEAF_MAX_AUDIO_CHANNELS, NULL);
3368  if (xxnchans > 0 && xxnchans < nchans) xnchans = xxnchans;
3369  }
3370  if (xnchans > nchans) {
3371  weed_instance_unref(orig_inst);
3372  return FALSE;
3373  }
3374  if (weed_get_int_value(channel, WEED_LEAF_AUDIO_CHANNELS, NULL) != nchans
3375  && (cflags & WEED_CHANNEL_REINIT_ON_LAYOUT_CHANGE))
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 
3449 void reinit_audio_gen(void) {
3450  int agen_key = mainw->agen_key;
3451  int ret;
3452 
3453  weed_plant_t *inst = rte_keymode_get_instance(agen_key, rte_key_getmode(mainw->agen_key));
3454 
3455  ret = weed_reinit_effect(inst, TRUE);
3456  if (ret == FILTER_SUCCESS || ret == FILTER_INFO_REINITED) {
3458  mainw->agen_key = agen_key;
3459  }
3460  weed_instance_unref(inst);
3461 }
3462 
3463 
3465 // apply audio as "rendered effect"
3466 
3467 static int audio_fd;
3468 static char *audio_file;
3469 
3470 off64_t audio_pos;
3471 
3472 weed_timecode_t aud_tc;
3473 
3474 boolean apply_rte_audio_init(void) {
3475  char *com;
3476 
3477  if (!prefs->conserve_space) {
3478  com = lives_strdup_printf("%s backup_audio %s", prefs->backend_sync, cfile->handle);
3479  lives_system(com, FALSE);
3480  lives_free(com);
3481 
3482  if (THREADVAR(com_failed)) {
3483  d_print_failed();
3484  return FALSE;
3485  }
3486  }
3487 
3488  audio_pos = (double)((cfile->start - 1) * cfile->arate * cfile->achans * cfile->asampsize / 8) / cfile->fps;
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 
3507 void apply_rte_audio_end(boolean del) {
3508  lives_close_buffered(audio_fd);
3509  if (del) lives_rm(audio_file);
3510  lives_free(audio_file);
3511 }
3512 
3513 
3514 boolean apply_rte_audio(int64_t nframes) {
3515  // CALLED When we are rendering audio to a file
3516 
3517  // - read nframes from clip or generator
3518  // - convert to float if necessary
3519  // - send to rte audio effects
3520  // - convert back to s16 or s8
3521  // - save to audio_fd
3522  weed_layer_t *layer;
3523  size_t tbytes;
3524  uint8_t *in_buff;
3525  float **fltbuf, *fltbufni = NULL;
3526  short *shortbuf = NULL;
3527  boolean rev_endian = FALSE;
3528 
3529  int i;
3530 
3531  int abigendian = cfile->signed_endian & AFORM_BIG_ENDIAN;
3532  int onframes;
3533 
3534  // read nframes of audio from clip or generator
3535 
3536  if ((abigendian && capable->byte_order == LIVES_LITTLE_ENDIAN) || (!abigendian &&
3537  capable->byte_order == LIVES_BIG_ENDIAN)) rev_endian = TRUE;
3538 
3539  tbytes = nframes * cfile->achans * cfile->asampsize / 8;
3540 
3541  if (mainw->agen_key == 0) {
3542  if (tbytes + audio_pos > cfile->afilesize) tbytes = cfile->afilesize - audio_pos;
3543  if (tbytes <= 0) return TRUE;
3544  nframes = tbytes / cfile->achans / (cfile->asampsize / 8);
3545  }
3546 
3547  onframes = nframes;
3548 
3549  in_buff = (uint8_t *)lives_calloc_safety(tbytes, 1);
3550  if (!in_buff) return FALSE;
3551 
3552  if (cfile->asampsize == 8) {
3553  shortbuf = (short *)lives_calloc_safety(tbytes / sizeof(short), sizeof(short));
3554  if (!shortbuf) {
3555  lives_free(in_buff);
3556  return FALSE;
3557  }
3558  }
3559 
3560  fltbuf = (float **)lives_calloc(cfile->achans, sizeof(float *));
3561 
3562  if (mainw->agen_key == 0) {
3563  // read from audio_fd
3564 
3565  tbytes = lives_read_buffered(audio_fd, in_buff, tbytes, FALSE);
3566 
3567  if (THREADVAR(read_failed) == audio_fd + 1) {
3568  THREADVAR(read_failed) = 0;
3569  do_read_failed_error_s(audio_file, NULL);
3570  lives_freep((void **)&THREADVAR(read_failed_file));
3571  lives_free(fltbuf);
3572  lives_free(in_buff);
3573  lives_freep((void **)&shortbuf);
3574  return FALSE;
3575  }
3576 
3577  if (cfile->asampsize == 8) {
3578  sample_move_d8_d16(shortbuf, in_buff, nframes, tbytes,
3579  1.0, cfile->achans, cfile->achans, 0);
3580  } else shortbuf = (short *)in_buff;
3581 
3582  nframes = tbytes / cfile->achans / (cfile->asampsize / 8);
3583 
3584  // convert to float
3585 
3586  for (i = 0; i < cfile->achans; i++) {
3587  // convert s16 to non-interleaved float
3588  fltbuf[i] = (float *)lives_calloc(nframes, sizeof(float));
3589  if (!fltbuf[i]) {
3590  for (--i; i >= 0; i--) {
3591  lives_free(fltbuf[i]);
3592  }
3593  lives_free(fltbuf);
3594  if (shortbuf != (short *)in_buff) lives_free(shortbuf);
3595  lives_free(in_buff);
3596  return FALSE;
3597  }
3598  lives_memset(fltbuf[i], 0, nframes * sizeof(float));
3599  if (nframes > 0) sample_move_d16_float(fltbuf[i], shortbuf + i, nframes, cfile->achans, \
3600  (cfile->signed_endian & AFORM_UNSIGNED), rev_endian,
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 
3688 boolean push_audio_to_channel(weed_plant_t *filter, weed_plant_t *achan, lives_audio_buf_t *abuf) {
3689  float **dst, *src;
3690 
3691  weed_plant_t *ctmpl;
3692 
3693  double scale;
3694 
3695  size_t samps, offs = 0;
3696  boolean rvary = FALSE, lvary = FALSE;
3697  int trate, tchans, xnchans, flags;
3698  size_t alen;
3699 
3700  int i;
3701 
3702  if (abuf->samples_filled == 0) {
3703  weed_layer_set_audio_data(achan, NULL, 0, 0, 0);
3704  return FALSE;
3705  }
3706 
3707  samps = abuf->samples_filled;
3708  //if (abuf->in_interleaf) samps /= abuf->in_achans;
3709 
3710  ctmpl = weed_get_plantptr_value(achan, WEED_LEAF_TEMPLATE, NULL);
3711 
3712  flags = weed_get_int_value(filter, WEED_LEAF_FLAGS, NULL);
3713  if (flags & WEED_FILTER_AUDIO_RATES_MAY_VARY) rvary = TRUE;
3714  if (flags & WEED_FILTER_CHANNEL_LAYOUTS_MAY_VARY) lvary = TRUE;
3715 
3716  if (!has_audio_chans_out(filter, FALSE)) {
3717  int maxlen = weed_chantmpl_get_max_audio_length(ctmpl);
3718  if (maxlen > 0) {
3719  if (abuf->in_interleaf) maxlen *= abuf->in_achans;
3720  if (maxlen < samps) {
3721  offs = samps - maxlen;
3722  samps = maxlen;
3723  }
3724  }
3725  }
3726 
3727  // TODO: can be list
3728  if (rvary && weed_plant_has_leaf(ctmpl, WEED_LEAF_AUDIO_RATE))
3729  trate = weed_get_int_value(ctmpl, WEED_LEAF_AUDIO_RATE, NULL);
3730  else if (weed_plant_has_leaf(filter, WEED_LEAF_AUDIO_RATE))
3731  trate = weed_get_int_value(filter, WEED_LEAF_AUDIO_RATE, NULL);
3732  else trate = DEFAULT_AUDIO_RATE;
3733 
3734  tchans = DEFAULT_AUDIO_CHANS;
3735  if (lvary && weed_plant_has_leaf(ctmpl, WEED_LEAF_AUDIO_CHANNELS))
3736  tchans = weed_get_int_value(ctmpl, WEED_LEAF_AUDIO_CHANNELS, NULL);
3737  else if (weed_plant_has_leaf(filter, WEED_LEAF_MAX_AUDIO_CHANNELS)) {
3738  xnchans = weed_get_int_value(filter, WEED_LEAF_MAX_AUDIO_CHANNELS, NULL);
3739  if (xnchans > 0 && xnchans < tchans) tchans = xnchans;
3740  }
3741 
3742 #ifdef DEBUG_AFB
3743  g_print("push from afb %d\n", abuf->samples_filled);
3744 #endif
3745 
3746  // plugin will get float, so we first convert to that
3747  if (!abuf->bufferf) {
3748  // try 8 bit -> 16
3749  if (abuf->buffer8 && !abuf->buffer16) {
3750  int swap = 0;
3751  if (!abuf->s8_signed) swap = SWAP_U_TO_S;
3752  abuf->s16_signed = TRUE;
3753  abuf->buffer16 = (short **)lives_calloc(abuf->out_achans, sizeof(short *));
3754  for (i = 0; i < abuf->out_achans; i++) {
3755  abuf->buffer16[i] = (short *)lives_calloc_safety(samps, sizeof(short));
3756  sample_move_d8_d16(abuf->buffer16[i], &abuf->buffer8[i][offs], samps, samps * sizeof(short),
3757  1.0, abuf->out_achans, abuf->out_achans, swap);
3758 
3759  }
3760  }
3761 
3762  // try convert S16 -> float
3763  if (abuf->buffer16) {
3764  abuf->bufferf = (float **)lives_calloc(abuf->out_achans, sizeof(float *));
3765  for (i = 0; i < abuf->out_achans; i++) {
3766  if (!abuf->in_interleaf) {
3767  abuf->bufferf[i] = (float *)lives_calloc_safety(abuf->samples_filled, sizeof(float));
3768  sample_move_d16_float(abuf->bufferf[i], &abuf->buffer16[0][offs], samps, 1,
3770  abuf->swap_endian, lives_vol_from_linear(cfile->vol));
3771  offs += abuf->samples_filled;
3772  } else {
3773  abuf->bufferf[i] = (float *)lives_calloc_safety(samps / abuf->out_achans, sizeof(float));
3774  sample_move_d16_float(abuf->bufferf[i], &abuf->buffer16[0][i], samps / abuf->in_achans, abuf->in_achans,
3776  abuf->swap_endian, lives_vol_from_linear(cfile->vol));
3777  }
3778  }
3779  abuf->out_interleaf = FALSE;
3780  }
3781  }
3782 
3783  if (!abuf->bufferf) return FALSE;
3784  // now we should have float
3785 
3786  if (abuf->in_interleaf) samps /= abuf->in_achans;
3787 
3788  // push to achan "audio_data", taking into account "audio_data_length" and "audio_channels"
3789 
3790  alen = samps;
3791 
3792  if (abuf->arate == 0) return FALSE;
3793  scale = (double)trate / (double)abuf->arate;
3794  alen = (size_t)(fabs(((double)alen * scale)));
3795 
3796  // malloc audio_data
3797  dst = (float **)lives_calloc(tchans, sizeof(float *));
3798 
3799  // copy data from abuf->bufferf[] to "audio_data"
3800  for (i = 0; i < tchans; i++) {
3801  pthread_mutex_lock(&mainw->abuf_mutex);
3802  src = abuf->bufferf[i % abuf->out_achans];
3803  if (src) {
3804  dst[i] = lives_calloc(alen, sizeof(float));
3805  if (abuf->arate == trate) {
3806  lives_memcpy(dst[i], src, alen * sizeof(float));
3807  } else {
3808  // needs resample
3809  sample_move_float_float(dst[i], src, alen, scale, 1);
3810  }
3811  } else dst[i] = NULL;
3812  pthread_mutex_unlock(&mainw->abuf_mutex);
3813  }
3814 
3815  // set channel values
3816  weed_channel_set_audio_data(achan, dst, trate, tchans, alen);
3817  lives_free(dst);
3818  return TRUE;
3819 }
3820 
3821 
3823 // audio streaming, older API
3824 
3826 
3827 boolean start_audio_stream(void) {
3828  const char *playername = "audiostreamer.pl";
3829  char *astream_name = NULL;
3830  char *astream_name_out = NULL;
3831 
3832  // playback plugin wants an audio stream - so fork and run the stream
3833  // player
3834  char *astname = lives_strdup_printf("livesaudio-%d.pcm", capable->mainpid);
3835  char *astname_out = lives_strdup_printf("livesaudio-%d.stream", capable->mainpid);
3836  char *astreamer, *com;
3837 
3838  int arate = 0;
3839  int afd;
3840  lives_alarm_t alarm_handle;
3841 
3842  ticks_t timeout = 0;
3843 
3844  astream_name = lives_build_filename(prefs->workdir, astname, NULL);
3845 
3846 #ifndef IS_MINGW
3847  mkfifo(astream_name, S_IRUSR | S_IWUSR);
3848 #endif
3849 
3850  astream_name_out = lives_build_filename(prefs->workdir, astname_out, NULL);
3851 
3852  lives_free(astname);
3853  lives_free(astname_out);
3854 
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 
3906 void stop_audio_stream(void) {
3907  if (astream_pgid > 0) {
3908  // if we were streaming audio, kill it
3909  const char *playername = "audiostreamer.pl";
3910  char *astname = lives_strdup_printf("livesaudio-%d.pcm", capable->mainpid);
3911  char *astname_out = lives_strdup_printf("livesaudio-%d.stream", capable->mainpid);
3912  char *astreamer = lives_build_filename(prefs->lib_dir, PLUGIN_EXEC_DIR, PLUGIN_AUDIO_STREAM, playername, NULL);
3913 
3914  char *astream_name = lives_build_filename(prefs->workdir, astname, NULL);
3915  char *astream_name_out = lives_build_filename(prefs->workdir, astname_out, NULL);
3916 
3917  char *com;
3918 
3919  lives_free(astname);
3920  lives_free(astname_out);
3921 
3922 #ifdef HAVE_PULSE_AUDIO
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 
3964 LIVES_GLOBAL_INLINE void audio_stream(void *buff, size_t nbytes, int fd) {
3965  if (fd != -1) {
3966  lives_write(fd, buff, nbytes, TRUE);
3967  }
3968 }
3969 
3970 
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
4004 void nullaudio_time_reset(int64_t offset) {
4005  mainw->nullaudo_startticks = lives_get_current_ticks();
4006  mainw->nullaudio_seek_posn = 0;
4007  mainw->nullaudio_arate = DEF_AUDIO_RATE;
4008  mainw->nullaudio_playing_file = -1;
4009  mainw->deltaticks = mainw->startticks = 0;
4010 }
4011 
4012 
4013 void nullaudio_arate_set(int arate) {
4014  mainw->nullaudio_arate = arate;
4015 }
4016 
4017 
4018 void nullaudio_seek_set(offs64_t seek_posn) {
4019  // (virtual) seek posn in bytes
4020  mainw->nullaudio_seek_posn = seek_posn;
4021 }
4022 
4023 
4024 void nullaudio_clip_set(int clipno) {
4025  mainw->nullaudio_playing_file = clipno;
4026 }
4027 
4028 
4029 int64_t nullaudio_update_seek_posn() {
4030  if (!CURRENT_CLIP_HAS_AUDIO) return mainw->nullaudio_seek_posn;
4031  else {
4032  ticks_t current_ticks = lives_get_current_ticks();
4033  mainw->nullaudio_seek_posn += ((int64_t)((double)(current_ticks - mainw->nullaudio_start_ticks) / USEC_TO_TICKS / ONE_MILLION. *
4034  mainw->nullaudio_arate)) * afile->achans * (afile->asampsize >> 3);
4035  mainw->nullaudo_startticks = current_ticks;
4036  if (mainw->nullaudio_seek_posn < 0) {
4037  if (mainw->nullaudio_loop == AUDIO_LOOP_NONE) {
4038  if (mainw->whentostop == STOP_ON_AUD_END) {
4040  }
4041  } else {
4042  if (mainw->nullaudio_loop == AUDIO_LOOP_PINGPONG) {
4043  mainw->nullaudio_arate = -mainw->nullaudio->arate;
4044  mainw->nullaudio_seek_posn = 0;
4045  } else mainw->nullaudio_seek_posn += mainw->nullaudio_seek_end;
4046  }
4047  } else {
4048  if (mainw->nullaudio_seek_posn > mainw->nullaudio_seek_end) {
4049  // reached the end, forwards
4050  if (mainw->nullaudio_loop == AUDIO_LOOP_NONE) {
4051  if (mainw->whentostop == STOP_ON_AUD_END) {
4053  }
4054  } else {
4055  if (mainw->nullaudio_loop == AUDIO_LOOP_PINGPONG) {
4056  mainw->nullaudio_arate = -mainw->nullaudio_arate;
4057  mainw->nullaudio_seek_posn = mainw->nullaudio_seek_end - (mainw->nullaudio_seek_pos - mainw->nullaudio_seek_end);
4058  } else {
4059  mainw->nullaudio_seek_posn -= mainw->nullaudio_seek_end;
4060  }
4061  nullaudio_set_rec_avals();
4062  // *INDENT-OFF*
4063  }}}}
4064  // *INDENT-ON*
4065 }
4066 
4067 
4068 void nullaudio_get_rec_avals(void) {
4069  lives_clip_t *afile = mainw->files[mainw->nullaudio_playing_file];
4070  mainw->rec_aclip = mainw->nulllaudio_playing_file;
4071 
4072  if (mainw->rec_aclip != -1) {
4073  mainw->rec_aseek = (double)mainw->nullaudio_seek_pos / (double)(afile->arps * afile->achans * afile->asampsize / 8);
4074  mainw->rec_avel = SIGNED_DIVIDE((double)pulsed->in_arate, (double)afile->arate);
4075  }
4076 }
4077 
4078 
4079 static void nullaudio_set_rec_avals(boolean is_forward) {
4080  // record direction change (internal)
4081  mainw->rec_aclip = mainw->nullaudio_playing_file;
4082  if (mainw->rec_aclip != -1) {
4083  nullaudio_get_rec_avals();
4084  }
4085 }
4086 
4087 #endif
lives_freep
boolean lives_freep(void **ptr)
Definition: utils.c:1411
CLIP_AUDIO_TIME
#define CLIP_AUDIO_TIME(clip)
Definition: main.h:827
LIVES_GLOBAL_INLINE
#define LIVES_GLOBAL_INLINE
Definition: main.h:239
mainwindow::jackd
void * jackd
jack audio player / transport
Definition: mainwindow.h:1453
AFORM_UNSIGNED
#define AFORM_UNSIGNED
Definition: main.h:786
float_deinterleave
boolean float_deinterleave(float *fbuffer, int nsamps, int nchans)
Definition: audio.c:1107
weed_apply_audio_effects
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)
Definition: effects-weed.c:3709
CLIP_DETAILS_HEADER_VERSION
@ CLIP_DETAILS_HEADER_VERSION
Definition: main.h:1161
lives_clip_t::header_version
int header_version
Definition: main.h:940
mainwindow::startticks
volatile ticks_t startticks
effective ticks when current frame was (should have been) displayed
Definition: mainwindow.h:997
LIVES_IS_PLAYING
#define LIVES_IS_PLAYING
Definition: main.h:840
get_audio_from_plugin
boolean get_audio_from_plugin(float **fbuffer, int nchans, int arate, int nsamps, boolean is_audio_thread)
Definition: audio.c:3332
LIVES_LOCAL_INLINE
#define LIVES_LOCAL_INLINE
Definition: main.h:246
lives_get_current_playback_ticks
ticks_t lives_get_current_playback_ticks(ticks_t origsecs, ticks_t origusecs, lives_time_source_t *time_source)
Definition: utils.c:1481
SIGNED_DIVIDE
#define SIGNED_DIVIDE(a, b)
Definition: main.h:295
do_write_failed_error_s
void do_write_failed_error_s(const char *s, const char *addinfo)
Definition: dialogs.c:3979
lives_ce_update_timeline
double lives_ce_update_timeline(int frame, double x)
pointer position in timeline
Definition: interface.c:207
lives_audio_buf_t::operation
lives_operation_t operation
Definition: audio.h:77
sample_move_d16_d8
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
lives_audio_buf_t::out_achans
int out_achans
channels for buffer* side
Definition: audio.h:96
astream_pgid
lives_pgid_t astream_pgid
Definition: audio.c:3825
preview_audio
void preview_audio(void)
Definition: audio.c:1835
WEED_LEAF_INIT_EVENT
#define WEED_LEAF_INIT_EVENT
Definition: events.h:52
weed_frame_event_get_audio_tracks
LIVES_GLOBAL_INLINE int weed_frame_event_get_audio_tracks(weed_event_t *event, int **clips, double **seeks)
Definition: events.c:59
lives_free
#define lives_free
Definition: machinestate.h:52
LIVES_WARN
#define LIVES_WARN(x)
Definition: main.h:1862
sample_move_d16_d16
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
start_audio_stream
boolean start_audio_stream(void)
Definition: audio.c:3827
SAMPLE_MAX_16BITI
#define SAMPLE_MAX_16BITI
Definition: audio.h:12
LIVES_SIGKILL
#define LIVES_SIGKILL
Definition: mainwindow.h:1854
quant_abytes
LIVES_GLOBAL_INLINE off_t quant_abytes(double seek, int arate, int achans, int asampsize)
Definition: resample.c:66
lives_audio_buf_t::eof
boolean eof
did we read EOF ? [readonly by client]
Definition: audio.h:79
has_audio_filters
boolean has_audio_filters(lives_af_t af_type)
Definition: effects-weed.c:3859
free_audio_frame_buffer
void free_audio_frame_buffer(lives_audio_buf_t *abuf)
Definition: audio.c:207
RENDER_BLOCK_SIZE
#define RENDER_BLOCK_SIZE
chunk size for interpolate/effect cycle
Definition: audio.h:39
mainwindow::audio_event
weed_plant_t * audio_event
Definition: mainwindow.h:1300
mainwindow::record
volatile boolean record
Definition: mainwindow.h:794
_vid_playback_plugin::render_audio_frame_float
boolean(* render_audio_frame_float)(float **audio, int nsamps)
Definition: plugins.h:175
lives_get_audio_file_name
LIVES_GLOBAL_INLINE char * lives_get_audio_file_name(int fnum)
Definition: audio.c:55
lives_audio_buf_t::buffer24
int32_t ** buffer24
sample data in 24 bit format (or NULL)
Definition: audio.h:113
AFORM_LITTLE_ENDIAN
#define AFORM_LITTLE_ENDIAN
Definition: main.h:784
lives_audio_buf_t
Definition: audio.h:76
USEC_TO_TICKS
#define USEC_TO_TICKS
multiplying factor uSec -> ticks_t (def. 100)
Definition: mainwindow.h:38
mainwindow::abuf_mutex
pthread_mutex_t abuf_mutex
mutices
Definition: mainwindow.h:1495
weed_layer_new
LIVES_GLOBAL_INLINE weed_layer_t * weed_layer_new(int layer_type)
Definition: colourspace.c:9655
render_audio_segment
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
_prefs::workdir
char workdir[PATH_MAX]
kept in locale encoding
Definition: preferences.h:61
SWAP_X_TO_L
#define SWAP_X_TO_L
endian swapping
Definition: audio.h:19
stop_audio_stream
void stop_audio_stream(void)
Definition: audio.c:3906
mainwindow::current_file
int current_file
Definition: mainwindow.h:727
IS_VALID_CLIP
#define IS_VALID_CLIP(clip)
Definition: main.h:808
CLIP_AUDIO_FILENAME
#define CLIP_AUDIO_FILENAME
Definition: mainwindow.h:537
lives_audio_track_state_t
Definition: main.h:646
mainwindow::vpp
_vid_playback_plugin * vpp
video plugin
Definition: mainwindow.h:1572
lives_audio_buf_t::samples_filled
volatile size_t samples_filled
number of samples filled (readonly client)
Definition: audio.h:124
get_weed_filter
weed_plant_t * get_weed_filter(int idx)
Definition: effects-weed.c:11014
lives_realloc
#define lives_realloc
Definition: machinestate.h:49
cfile
#define cfile
Definition: main.h:1833
mainwindow::preview
boolean preview
Definition: mainwindow.h:757
effects.h
ASERVER_CMD_FILE_CLOSE
#define ASERVER_CMD_FILE_CLOSE
Definition: audio.h:58
LIVES_READ_OPERATION
@ LIVES_READ_OPERATION
Definition: audio.h:71
lives_lseek_buffered_rdonly_absolute
off_t lives_lseek_buffered_rdonly_absolute(int fd, off_t offset)
Definition: utils.c:907
weed_channel_set_audio_data
WEED_GLOBAL_INLINE weed_layer_t * weed_channel_set_audio_data(weed_plant_t *channel, float **data, int arate, int naudchans, int nsamps)
Definition: weed-effects-utils.c:570
lives_audio_buf_t::_shrink_factor
double _shrink_factor
resampling ratio
Definition: audio.h:138
lives_audio_buf_t::_cin_interleaf
int _cin_interleaf
Definition: audio.h:135
CLIP_DETAILS_ACHANS
@ CLIP_DETAILS_ACHANS
Definition: main.h:1150
prefs
_prefs * prefs
Definition: preferences.h:847
_prefs::lib_dir
char lib_dir[PATH_MAX]
Definition: preferences.h:75
_prefs::audio_player
short audio_player
Definition: preferences.h:40
audio_stream
LIVES_GLOBAL_INLINE void audio_stream(void *buff, size_t nbytes, int fd)
Definition: audio.c:3964
mainwindow::video_seek_ready
volatile boolean video_seek_ready
Definition: mainwindow.h:939
lives_open2
int lives_open2(const char *pathname, int flags)
Definition: utils.c:99
lives_audio_buf_t::s16_signed
boolean s16_signed
Definition: audio.h:119
lives_audio_buf_t::start_sample
size_t start_sample
used for reading (readonly server)
Definition: audio.h:125
lives_open3
int lives_open3(const char *pathname, int flags, mode_t mode)
Definition: utils.c:94
_prefs::push_audio_to_gens
boolean push_audio_to_gens
Definition: preferences.h:424
FILTER_SUCCESS
@ FILTER_SUCCESS
Definition: effects-weed.h:15
SWAP_U_TO_S
#define SWAP_U_TO_S
sign swapping
Definition: audio.h:15
lives_alarm_clear
boolean lives_alarm_clear(lives_alarm_t alarm_handle)
Definition: utils.c:1732
CLIP_TEMP_AUDIO_FILENAME
#define CLIP_TEMP_AUDIO_FILENAME
Definition: mainwindow.h:538
_prefs::backend_sync
char backend_sync[PATH_MAX *4]
Definition: preferences.h:410
TICKS_PER_SECOND_DBL
#define TICKS_PER_SECOND_DBL
actually microseconds / 100.
Definition: mainwindow.h:37
lives_audio_buf_t::_filebuffer
uint8_t * _filebuffer
raw data to/from file - can be cast to int16_t
Definition: audio.h:128
free_jack_audio_buffers
void free_jack_audio_buffers(void)
Definition: audio.c:2748
CANCEL_KILL
@ CANCEL_KILL
normal - kill background processes working on current clip
Definition: main.h:759
pad_with_silence
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
AUD_PLAYER_NONE
#define AUD_PLAYER_NONE
Definition: preferences.h:41
_prefs::aplayer
char aplayer[512]
Definition: preferences.h:54
append_to_audio_buffer16
void append_to_audio_buffer16(void *src, uint64_t nsamples, int channum)
Definition: audio.c:118
sizdbl
ssize_t sizdbl
Definition: main.c:102
preview_aud_vol
void preview_aud_vol(void)
Definition: audio.c:1991
lives_buffered_rdonly_set_reversed
boolean lives_buffered_rdonly_set_reversed(int fd, boolean val)
Definition: utils.c:681
capability::mainpid
pid_t mainpid
Definition: main.h:591
mainwindow::agen_needs_reinit
volatile boolean agen_needs_reinit
Definition: mainwindow.h:1650
CLIP_DETAILS_ASAMPS
@ CLIP_DETAILS_ASAMPS
Definition: main.h:1153
EXTRA_BYTES
#define EXTRA_BYTES
TODO - split into: memory, files, sysops, threads.
Definition: machinestate.h:16
LIVES_DEFAULT_TIMEOUT
#define LIVES_DEFAULT_TIMEOUT
Definition: mainwindow.h:43
do_auto_dialog
boolean do_auto_dialog(const char *text, int type)
Definition: dialogs.c:2844
fastrand
LIVES_GLOBAL_INLINE uint64_t fastrand(void)
Definition: machinestate.c:40
AUDIO_LOOP_NONE
@ AUDIO_LOOP_NONE
Definition: audio.h:146
mainwindow::cache_buffer_mutex
pthread_mutex_t cache_buffer_mutex
sync for jack playback termination
Definition: mainwindow.h:1502
WEED_LEAF_HOST_KEEP_ADATA
#define WEED_LEAF_HOST_KEEP_ADATA
Definition: audio.h:51
lives_alarm_t
int lives_alarm_t
Definition: mainwindow.h:696
lives_nanosleep
#define lives_nanosleep(nanosec)
Definition: machinestate.h:307
push_audio_to_channel
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
mainwindow::event_list
weed_event_t * event_list
current event_list, for recording
Definition: mainwindow.h:803
lives_open_buffered_rdonly
int lives_open_buffered_rdonly(const char *pathname)
Definition: utils.c:636
LIVES_PREVIEW_TYPE_VIDEO_AUDIO
#define LIVES_PREVIEW_TYPE_VIDEO_AUDIO
Definition: interface.h:170
SILENCE_BLOCK_SIZE
#define SILENCE_BLOCK_SIZE
size of silent block in bytes
Definition: audio.h:42
ticks_t
int64_t ticks_t
Definition: main.h:97
weed_inst_in_param
weed_plant_t * weed_inst_in_param(weed_plant_t *inst, int param_num, boolean skip_hidden, boolean skip_internal)
Definition: effects-weed.c:8724
XSAMPLES
#define XSAMPLES
buffer size (output samples) for (semi) realtime audio (bytes == XSAMPLES * achans * samp....
Definition: audio.h:47
CLIP_DETAILS_AENDIAN
@ CLIP_DETAILS_AENDIAN
Definition: main.h:1152
mainwindow::rec_aclip
volatile int rec_aclip
recording values - to be inserted at the following video frame
Definition: mainwindow.h:967
get_first_event
LIVES_GLOBAL_INLINE weed_plant_t * get_first_event(weed_plant_t *event_list)
Definition: events.c:119
LIVES_PREVIEW_TYPE_VIDEO_ONLY
#define LIVES_PREVIEW_TYPE_VIDEO_ONLY
Definition: interface.h:171
do_error_dialog
LIVES_GLOBAL_INLINE LiVESResponseType do_error_dialog(const char *text)
Definition: dialogs.c:749
weed_filter_get_flags
WEED_GLOBAL_INLINE int weed_filter_get_flags(weed_plant_t *filter)
Definition: weed-effects-utils.c:176
init_pulse_audio_buffers
void init_pulse_audio_buffers(int achans, int arate, boolean exact)
Definition: audio.c:2729
lives_audio_buf_t::arate
int arate
Definition: audio.h:88
mainwindow::fx_mutex
pthread_mutex_t fx_mutex[FX_KEYS_MAX]
used to prevent fx processing when it is scheduled for deinit
Definition: mainwindow.h:1497
audio_pos
off64_t audio_pos
Definition: audio.c:3470
AF_TYPE_NONA
@ AF_TYPE_NONA
Definition: effects.h:43
lives_audio_buf_t::out_asamps
int out_asamps
Definition: audio.h:98
threaded_dialog_spin
void threaded_dialog_spin(double fraction)
Definition: dialogs.c:3823
lives_audio_track_state_t::seek
double seek
Definition: main.h:648
CLIP_DETAILS_ASIGNED
@ CLIP_DETAILS_ASIGNED
Definition: main.h:1151
get_track_visibility_at_tc
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
TRUE
#define TRUE
Definition: videoplugin.h:59
sizint
ssize_t sizint
type sizes
Definition: main.c:102
capability::umask
mode_t umask
Definition: main.h:597
weed_chantmpl_get_flags
WEED_GLOBAL_INLINE int weed_chantmpl_get_flags(weed_plant_t *chantmpl)
Definition: weed-effects-utils.c:290
clear_audio_stream
void clear_audio_stream(void)
Definition: audio.c:3949
free_pulse_audio_buffers
void free_pulse_audio_buffers(void)
Definition: audio.c:2768
aud_tc
weed_timecode_t aud_tc
Definition: audio.c:3472
sample_move_float_float
void sample_move_float_float(float *dst, float *src, uint64_t nsamples, double scale, int dst_skip)
Definition: audio.c:745
lives_read_buffered
ssize_t lives_read_buffered(int fd, void *buf, ssize_t count, boolean allow_less)
Definition: utils.c:924
lives_memset
#define lives_memset
Definition: machinestate.h:61
AUDIO_PLAYER_PULSE_AUDIO
#define AUDIO_PLAYER_PULSE_AUDIO
used for display, alternate pref and alternate startup opt (-aplayer pulseaudio)
Definition: preferences.h:52
mainwindow::whentostop
volatile lives_whentostop_t whentostop
Definition: mainwindow.h:929
weed_apply_audio_effects_rt
void weed_apply_audio_effects_rt(weed_layer_t *alayer, weed_timecode_t tc, boolean analysers_only, boolean is_audio_thread)
Definition: effects-weed.c:3743
THREADVAR
#define THREADVAR(var)
Definition: machinestate.h:531
LIVES_PREVIEW_TYPE_AUDIO_ONLY
#define LIVES_PREVIEW_TYPE_AUDIO_ONLY
Definition: interface.h:172
CURRENT_CLIP_HAS_AUDIO
#define CURRENT_CLIP_HAS_AUDIO
Definition: main.h:818
is_pure_audio
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
mainwindow::cancelled
volatile lives_cancel_t cancelled
Definition: mainwindow.h:798
events.h
lives_audio_buf_t::seek
off_t seek
Definition: audio.h:85
lives_fork
lives_pid_t lives_fork(const char *com)
Definition: utils.c:288
_prefs::audio_opts
volatile uint32_t audio_opts
Definition: preferences.h:254
is_realtime_aplayer
#define is_realtime_aplayer(ptype)
Definition: audio.h:236
weed_event_get_type
LIVES_GLOBAL_INLINE int weed_event_get_type(weed_event_t *event)
Definition: events.c:31
mainwindow::afilter_map
weed_plant_t * afilter_map
Definition: mainwindow.h:1299
lives_open_buffered_writer
int lives_open_buffered_writer(const char *pathname, int mode, boolean append)
Definition: utils.c:706
lives_audio_buf_t::die
volatile boolean die
set to TRUE to shut down thread
Definition: audio.h:140
sample_move_d16_float
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
RECA_WINDOW_GRAB
@ RECA_WINDOW_GRAB
Definition: audio.h:197
CANCEL_ERROR
@ CANCEL_ERROR
cancelled because of error
Definition: main.h:740
callbacks.h
mainwindow::afb
lives_audio_buf_t * afb[2]
used for buffering / feeding audio to video generators
Definition: mainwindow.h:1698
weed_get_idx_for_hashname
int weed_get_idx_for_hashname(const char *hashname, boolean fullname)
fullname includes author and version
Definition: effects-weed.c:10840
lives_clip_t::cb_src
int cb_src
source clip for clipboard; for other clips, may be used to hold some temporary linkage
Definition: main.h:1086
_prefs::audio_src
int audio_src
Definition: preferences.h:204
capable
capability * capable
Definition: main.h:627
mainwindow::preview_rendering
boolean preview_rendering
Definition: mainwindow.h:758
d_print
void d_print(const char *fmt,...)
Definition: utils.c:2542
lives_audio_track_state_t::afile
int afile
Definition: main.h:647
on_playsel_activate
void on_playsel_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:4566
mainwindow::rec_aseek
volatile double rec_aseek
Definition: mainwindow.h:969
mainwindow::avseek_mutex
pthread_mutex_t avseek_mutex
Definition: mainwindow.h:938
WEED_LEAF_IN_TRACKS
#define WEED_LEAF_IN_TRACKS
Definition: events.h:47
run_process_func
lives_filter_error_t run_process_func(weed_plant_t *instance, weed_timecode_t tc, int key)
Definition: effects-weed.c:2799
filter_mutex_unlock
LIVES_GLOBAL_INLINE int filter_mutex_unlock(int key)
Definition: effects-weed.c:108
reverse_buffer
boolean reverse_buffer(uint8_t *buff, size_t count, size_t chunk)
Definition: machinestate.c:2509
sample_move_d8_d16
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
sample_move_abuf_float
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
mainwindow::deltaticks
ticks_t deltaticks
deltaticks for scratching
Definition: mainwindow.h:1006
lives_clip_t::signed_endian
uint32_t signed_endian
bitfield
Definition: main.h:909
WEED_LEAF_HOST_TAG
#define WEED_LEAF_HOST_TAG
Definition: effects-weed.h:66
lives_audio_buf_t::in_interleaf
boolean in_interleaf
Definition: audio.h:92
audio_frame_to_atstate
LIVES_GLOBAL_INLINE lives_audio_track_state_t * audio_frame_to_atstate(weed_event_t *event, int *ntracks)
Definition: audio.c:2405
init_audio_frame_buffers
void init_audio_frame_buffers(short aplayer)
Definition: audio.c:155
reinit_audio_gen
void reinit_audio_gen(void)
Definition: audio.c:3449
mainwindow::origsecs
ticks_t origsecs
playback start seconds - subtracted from all other ticks to keep numbers smaller
Definition: mainwindow.h:1000
mainwindow::playing_sel
boolean playing_sel
list of set names in current workdir, mau be NULL
Definition: mainwindow.h:756
_vid_playback_plugin::audio_codec
uint32_t audio_codec
Definition: plugins.h:169
lives_audio_buf_t::bytesize
ssize_t bytesize
Definition: audio.h:90
avsync_force
LIVES_GLOBAL_INLINE void avsync_force(void)
Definition: audio.c:2785
lives_audio_buf_t::_cout_interleaf
int _cout_interleaf
Definition: audio.h:136
get_file_size
off_t get_file_size(int fd)
Definition: machinestate.c:943
PLUGIN_EXEC_DIR
#define PLUGIN_EXEC_DIR
Definition: mainwindow.h:599
lives_audio_buf_t::fileno
int fileno
Definition: audio.h:80
get_float_audio_val_at_time
float get_float_audio_val_at_time(int fnum, int afd, double secs, int chnum, int chans)
Definition: audio.c:374
STOP_ON_AUD_END
@ STOP_ON_AUD_END
Definition: main.h:695
switch_aud_to_none
void switch_aud_to_none(boolean set_pref)
Definition: utils.c:4001
mainwindow::abufs_to_fill
volatile int abufs_to_fill
Definition: mainwindow.h:1592
WEED_LEAF_FILTER
#define WEED_LEAF_FILTER
Definition: events.h:44
d_print_failed
void d_print_failed(void)
Definition: utils.c:2615
resync_audio
boolean resync_audio(double frameno)
resync audio playback to the current video frame
Definition: audio.c:2822
lives_audio_buf_t::bufferf
float ** bufferf
sample data in float format (or NULL)
Definition: audio.h:115
process_events
weed_plant_t * process_events(weed_plant_t *next_event, boolean process_audio, weed_timecode_t curr_tc)
Definition: events.c:3082
mainwindow::playing_file
int playing_file
which number file we are playing (or -1) [generally mainw->current_file]
Definition: mainwindow.h:943
fill_abuffer_from
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
lives_buffered_offset
off_t lives_buffered_offset(int fd)
Definition: utils.c:1364
lives_pgid_t
int lives_pgid_t
Definition: main.h:118
mainwindow::files
lives_clip_t * files[MAX_FILES+1]
+1 for the clipboard
Definition: mainwindow.h:729
lives_cancel_t
lives_cancel_t
cancel reason
Definition: main.h:699
save_clip_value
boolean save_clip_value(int which, lives_clip_details_t, void *val)
Definition: utils.c:5175
audiofile_get_maxvol
float audiofile_get_maxvol(int fnum, double start, double end, float thresh)
Definition: audio.c:248
apply_rte_audio_init
boolean apply_rte_audio_init(void)
Definition: audio.c:3474
mainwindow::audio_seek_ready
volatile boolean audio_seek_ready
Definition: mainwindow.h:940
CANCEL_NONE
@ CANCEL_NONE
no cancel
Definition: main.h:701
adjust_clip_volume
boolean adjust_clip_volume(int fileno, float newvol, boolean make_backup)
Definition: audio.c:2001
RECA_GENERATED
@ RECA_GENERATED
Definition: audio.h:201
audio_cache_get_buffer
LIVES_GLOBAL_INLINE lives_audio_buf_t * audio_cache_get_buffer(void)
Definition: audio.c:3324
get_next_audio_frame_event
weed_plant_t * get_next_audio_frame_event(weed_plant_t *event)
Definition: events.c:380
init_jack_audio_buffers
void init_jack_audio_buffers(int achans, int arate, boolean exact)
Definition: audio.c:2708
AUD_DIFF_MIN
#define AUD_DIFF_MIN
ignore audio seek differences < than this (seconds)
Definition: events.h:94
WEED_LEAF_DEINIT_EVENT
#define WEED_LEAF_DEINIT_EVENT
Definition: events.h:76
mainwindow::pulsed
void * pulsed
pulseaudio player
Definition: mainwindow.h:1463
lives_close_buffered
int lives_close_buffered(int fd)
Definition: utils.c:716
mainwindow::play_start
frames_t play_start
Definition: mainwindow.h:931
mainwindow::aframeno
double aframeno
and the audio 'frame' for when we are looping
Definition: mainwindow.h:962
lives_audio_buf_t::buffer32
int32_t ** buffer32
sample data in 32 bit format (or NULL)
Definition: audio.h:114
DEFAULT_AUDIO_RATE
#define DEFAULT_AUDIO_RATE
defaults for when not specifed
Definition: audio.h:23
get_achannel_name
LIVES_GLOBAL_INLINE char * get_achannel_name(int totchans, int idx)
Definition: audio.c:28
lives_killpg
int lives_killpg(lives_pgid_t pgrp, int sig)
Definition: utils.c:1432
NSTOREDFDS
#define NSTOREDFDS
Definition: audio.h:33
lives_audio_buf_t::_cseek
int _cseek
current seek pos
Definition: audio.h:133
audio_process_events_to
LIVES_LOCAL_INLINE void audio_process_events_to(weed_timecode_t tc)
Definition: audio.c:1241
weed_layer_set_audio_data
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
CLIP_DETAILS_ARATE
@ CLIP_DETAILS_ARATE
Definition: main.h:1148
LIVES_CLIP_HEADER_VERSION
#define LIVES_CLIP_HEADER_VERSION
Definition: main.h:941
lives_get_current_ticks
LIVES_GLOBAL_INLINE ticks_t lives_get_current_ticks(void)
Definition: machinestate.c:835
lives_clip_t::arps
int arps
audio physical sample rate (i.e the "normal" sample rate of the clip when played at 1,...
Definition: main.h:905
mainwindow::jackd_read
void * jackd_read
dummy
Definition: mainwindow.h:1454
lives_audio_buf_t::samp_space
size_t samp_space
buffer space in samples (* by sizeof(type) to get bytesize) [if interleaf, also * by chans]
Definition: audio.h:103
rte_keymode_get_instance
weed_plant_t * rte_keymode_get_instance(int key, int mode)
returns refcounted filter_instance bound to key/mode (or NULL)
Definition: effects-weed.c:9450
lives_strdup_printf
#define lives_strdup_printf(fmt,...)
Definition: support.c:27
PLUGIN_AUDIO_STREAM
#define PLUGIN_AUDIO_STREAM
Definition: plugins.h:101
mainwindow::ext_audio
volatile boolean ext_audio
using external video playback plugin to stream audio
Definition: mainwindow.h:774
WEED_LEAF_INDEX
#define WEED_LEAF_INDEX
Definition: events.h:58
get_event_timecode
LIVES_GLOBAL_INLINE weed_timecode_t get_event_timecode(weed_plant_t *plant)
Definition: events.c:98
lives_calloc
#define lives_calloc
Definition: machinestate.h:67
lives_clip_t::opening
boolean opening
Definition: main.h:946
audio_player_get_display_name
LIVES_GLOBAL_INLINE const char * audio_player_get_display_name(const char *aplayer)
Definition: audio.c:65
lives_audio_buf_t::_cfileno
int _cfileno
current fileno
Definition: audio.h:132
mainwindow::force_show
boolean force_show
Definition: mainwindow.h:1763
mainwindow::audio_filewriteend_mutex
pthread_mutex_t audio_filewriteend_mutex
sync for ending writing audio to file
Definition: mainwindow.h:1503
weed_layer_t
weed_plant_t weed_layer_t
Definition: colourspace.h:71
audio_free_fnames
void audio_free_fnames(void)
Definition: audio.c:71
mainwindow::is_rendering
boolean is_rendering
Definition: mainwindow.h:821
audio_cache_init
lives_audio_buf_t * audio_cache_init(void)
Definition: audio.c:3238
handle_audio_timeout
LIVES_GLOBAL_INLINE lives_cancel_t handle_audio_timeout(void)
Definition: audio.c:3971
lives_clip_t::vol
float vol
relative volume level / gain; sizeof array will be equal to achans
Definition: main.h:910
append_to_audio_bufferf
void append_to_audio_bufferf(float *src, uint64_t nsamples, int channum)
Definition: audio.c:82
mainwindow::ascrap_file
int ascrap_file
scrap file for recording audio scraps
Definition: mainwindow.h:875
AUDIO_OPTS_FOLLOW_FPS
#define AUDIO_OPTS_FOLLOW_FPS
Definition: preferences.h:256
lives_audio_buf_t::s8_signed
boolean s8_signed
Definition: audio.h:118
_prefs::num_rtaudiobufs
int num_rtaudiobufs
Definition: preferences.h:325
wake_audio_thread
void wake_audio_thread(void)
Definition: audio.c:3230
sample_silence_stream
void sample_silence_stream(int nchans, int64_t nframes)
Definition: audio.c:421
lives_audio_buf_t::_csamp_space
size_t _csamp_space
current sample buffer size in single channel samples
Definition: audio.h:130
mainwindow::write_abuf
int write_abuf
audio buffer number to write to (for multitrack)
Definition: mainwindow.h:1591
lives_memcpy
#define lives_memcpy
Definition: machinestate.h:55
mainwindow::rec_avel
volatile double rec_avel
Definition: mainwindow.h:968
CANCEL_AUDIO_ERROR
@ CANCEL_AUDIO_ERROR
cancelled because of soundcard error
Definition: main.h:743
AFORM_SIGNED
#define AFORM_SIGNED
Definition: main.h:783
mainwindow::multitrack
lives_mt * multitrack
holds a pointer to the entire multitrack environment; NULL in Clip Edit mode
Definition: mainwindow.h:1087
lives_audio_buf_t::shrink_factor
double shrink_factor
resampling ratio
Definition: audio.h:101
RECA_NEW_CLIP
@ RECA_NEW_CLIP
Definition: audio.h:198
lives_alarm_check
ticks_t lives_alarm_check(lives_alarm_t alarm_handle)
Definition: utils.c:1687
lives_vol_from_linear
#define lives_vol_from_linear(vol)
Definition: audio.h:269
mainwindow::suppress_dprint
boolean suppress_dprint
tidy up, e.g. by blocking "switched to file..." and "closed file..." messages
Definition: mainwindow.h:1537
lives_clip_t::laudio_time
double laudio_time
Definition: main.h:929
mainwindow::aud_rec_fd
int aud_rec_fd
fd of file we are recording audio to
Definition: mainwindow.h:1525
mainwindow::record_paused
volatile boolean record_paused
pause during recording
Definition: mainwindow.h:1557
weed_event_t
weed_plant_t weed_event_t
Definition: events.h:97
sample_silence_dS
LIVES_GLOBAL_INLINE void sample_silence_dS(float *dst, uint64_t nsamples)
Definition: audio.c:415
get_audio_and_effects_state_at
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
do_write_failed_error_s_with_retry
LiVESResponseType do_write_failed_error_s_with_retry(const char *fname, const char *errtext)
Definition: dialogs.c:4058
MAX_AUDIO_MEM
#define MAX_AUDIO_MEM
TODO ** - make configurable - audio buffer size for rendering.
Definition: audio.h:36
lives_buffered_orig_size
size_t lives_buffered_orig_size(int fd)
Definition: utils.c:1377
main.h
WEED_LAYER_TYPE_AUDIO
#define WEED_LAYER_TYPE_AUDIO
Definition: colourspace.h:222
mainwindow::play_end
frames_t play_end
Definition: mainwindow.h:931
float_interleave
boolean float_interleave(float *fbuffer, int nsamps, int nchans)
Definition: audio.c:1125
lives_lseek_buffered_rdonly
off_t lives_lseek_buffered_rdonly(int fd, off_t offset)
Definition: utils.c:895
SWAP_S_TO_U
#define SWAP_S_TO_U
signed to unsigned
Definition: audio.h:16
get_enabled_channel
weed_plant_t * get_enabled_channel(weed_plant_t *inst, int which, boolean is_in)
for FILTER_INST
Definition: effects-weed.c:536
resample.h
_prefs::sleep_time
int sleep_time
Definition: preferences.h:176
AUDIO_SRC_EXT
#define AUDIO_SRC_EXT
Definition: preferences.h:206
AUDIO_SRC_INT
#define AUDIO_SRC_INT
Definition: preferences.h:205
mainw
mainwindow * mainw
Definition: main.c:103
lives_lseek_buffered_writer
off_t lives_lseek_buffered_writer(int fd, off_t offset)
Definition: utils.c:1338
mainwindow::pconx
lives_pconnect_t * pconx
list of out -> in param connections
Definition: mainwindow.h:1668
weed_instance_unref
LIVES_GLOBAL_INLINE int weed_instance_unref(weed_plant_t *inst)
Definition: effects-weed.c:6234
lives_audio_track_state_t::vel
double vel
Definition: main.h:649
AUDIO_PLAYER_PULSE
#define AUDIO_PLAYER_PULSE
used in pref and for external players (e.g -ao pulse, -aplayer pulse)
Definition: preferences.h:51
lives_rec_audio_type_t
lives_rec_audio_type_t
Definition: audio.h:195
MAX_AUDIO_TRACKS
#define MAX_AUDIO_TRACKS
Definition: multitrack.h:1046
mainwindow::audio_frame_buffer
volatile lives_audio_buf_t * audio_frame_buffer
used for buffering / feeding audio to video generators
Definition: mainwindow.h:1697
_prefs::force_system_clock
boolean force_system_clock
Definition: preferences.h:366
ONE_MILLION_DBL
#define ONE_MILLION_DBL
Definition: mainwindow.h:32
apply_rte_audio_end
void apply_rte_audio_end(boolean del)
Definition: audio.c:3507
CLIP_DETAILS_PB_ARATE
@ CLIP_DETAILS_PB_ARATE
Definition: main.h:1149
WEED_LEAF_HOST_NEXT_INSTANCE
#define WEED_LEAF_HOST_NEXT_INSTANCE
Definition: effects-weed.h:104
lives_write_buffered
ssize_t lives_write_buffered(int fd, const char *buf, ssize_t count, boolean allow_fail)
Definition: utils.c:1226
aframe_to_atstate
LIVES_LOCAL_INLINE lives_audio_track_state_t * aframe_to_atstate(weed_plant_t *event)
Definition: audio.c:2400
weed_channel_get_template
WEED_GLOBAL_INLINE weed_plant_t * weed_channel_get_template(weed_plant_t *channel)
Definition: weed-effects-utils.c:513
lives_audio_buf_t::is_ready
volatile boolean is_ready
Definition: audio.h:78
lives_system
int lives_system(const char *com, boolean allow_error)
Definition: utils.c:145
weed_layer_get_audio_data
LIVES_GLOBAL_INLINE float ** weed_layer_get_audio_data(weed_layer_t *layer, int *naudchans)
Definition: colourspace.c:13921
weed_layer_free
LIVES_GLOBAL_INLINE weed_layer_t * weed_layer_free(weed_layer_t *layer)
frees pixel_data for a layer, then the layer itself
Definition: colourspace.c:13883
mainwindow::abuf_frame_mutex
pthread_mutex_t abuf_frame_mutex
used to synch audio buffer for generators
Definition: mainwindow.h:1496
weed_instance_get_filter
weed_plant_t * weed_instance_get_filter(weed_plant_t *inst, boolean get_compound_parent)
Definition: effects-weed.c:180
lives_audio_buf_t::out_interleaf
boolean out_interleaf
Definition: audio.h:93
lives_audio_buf_t::swap_endian
int swap_endian
Definition: audio.h:100
normalise_audio
boolean normalise_audio(int fnum, double start, double end, float thresh)
Definition: audio.c:280
get_next_event
LIVES_GLOBAL_INLINE weed_plant_t * get_next_event(weed_plant_t *event)
Definition: events.c:114
AUD_PLAYER_PULSE
#define AUD_PLAYER_PULSE
Definition: preferences.h:44
weed_event_get_timecode
LIVES_GLOBAL_INLINE weed_timecode_t weed_event_get_timecode(weed_event_t *event)
Definition: events.c:89
AUD_PLAYER_JACK
#define AUD_PLAYER_JACK
Definition: preferences.h:43
RECA_EXTERNAL
@ RECA_EXTERNAL
Definition: audio.h:200
do_read_failed_error_s
void do_read_failed_error_s(const char *s, const char *addinfo)
Definition: dialogs.c:4034
CANCEL_SOFT
@ CANCEL_SOFT
just cancel in GUI (for keep, etc)
Definition: main.h:760
lives_clip_t
corresponds to one clip in the GUI
Definition: main.h:877
lives_audio_buf_t::sequential
boolean sequential
hint that we will read sequentially starting from seek
Definition: audio.h:105
lives_calloc_safety
LIVES_GLOBAL_INLINE void * lives_calloc_safety(size_t nmemb, size_t xsize)
Definition: machinestate.c:603
lives_audio_buf_t::_fd
int _fd
file descriptor
Definition: audio.h:131
sample_move_abuf_int16
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
lives_write
ssize_t lives_write(int fd, livesconstpointer buf, ssize_t count, boolean allow_fail)
mainwindow::pulsed_read
void * pulsed_read
Definition: mainwindow.h:1464
apply_rte_audio
boolean apply_rte_audio(int64_t nframes)
Definition: audio.c:3514
has_audio_chans_out
boolean has_audio_chans_out(weed_plant_t *filter, boolean count_opt)
Definition: effects-weed.c:695
do_abort_cancel_retry_dialog
LIVES_GLOBAL_INLINE LiVESResponseType do_abort_cancel_retry_dialog(const char *text)
Definition: dialogs.c:708
lives_audio_buf_t::in_asamps
int in_asamps
Definition: audio.h:97
mainwindow::fx1_val
double fx1_val
Definition: mainwindow.h:1049
SAMPLE_MAX_16BIT_P
#define SAMPLE_MAX_16BIT_P
Definition: audio.h:10
ONE_MILLION
#define ONE_MILLION
Definition: mainwindow.h:27
pconx_chain_data
boolean pconx_chain_data(int key, int mode, boolean is_audio_thread)
Definition: effects-data.c:1390
audio.h
CLIP_DECAY
#define CLIP_DECAY
Definition: audio.c:776
CANCEL_AUD_END
@ CANCEL_AUD_END
video playback completed
Definition: main.h:737
weed_chantmpl_get_max_audio_length
WEED_GLOBAL_INLINE int weed_chantmpl_get_max_audio_length(weed_plant_t *chantmpl)
Definition: weed-effects-utils.c:295
lives_audio_buf_t::_cbytesize
ssize_t _cbytesize
current _filebuffer bytesize; if this changes we need to realloc _filebuffer
Definition: audio.h:129
SAMPLE_MAX_16BIT_N
#define SAMPLE_MAX_16BIT_N
Definition: audio.h:11
mainwindow::currticks
volatile ticks_t currticks
wall clock time, updated whenever lives_get_*_ticks is called
Definition: mainwindow.h:1005
lives_audio_buf_t::buffer8
uint8_t ** buffer8
sample data in 8 bit format (or NULL)
Definition: audio.h:108
mainwindow::filter_map
weed_plant_t * filter_map
Definition: mainwindow.h:1298
mainwindow::cancel_type
lives_cancel_type_t cancel_type
Definition: mainwindow.h:799
lives_audio_buf_t::_casamps
int _casamps
current out_asamps
Definition: audio.h:137
rte_key_getmode
int rte_key_getmode(int key)
returns current active mode for a key (or -1)
Definition: effects-weed.c:9424
lives_clip_t::asampsize
int asampsize
audio sample size in bits (8 or 16)
Definition: main.h:908
aud_fade
void aud_fade(int fileno, double startt, double endt, double startv, double endv)
fade in/fade out
Definition: audio.c:1813
mainwindow::agen_samps_count
uint64_t agen_samps_count
count of samples since init
Definition: mainwindow.h:1651
mainwindow::agen_key
volatile int agen_key
which fx key is generating audio [1 based] (or 0 for none)
Definition: mainwindow.h:1649
mainwindow::vpp_stream_mutex
pthread_mutex_t vpp_stream_mutex
prevent from writing audio when stream is closing
Definition: mainwindow.h:1501
sample_move_float_int
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
DEF_FILE_PERMS
#define DEF_FILE_PERMS
non-executable, is modified by the umask
Definition: main.h:209
lives_clip_t::arate
int arate
current audio playback rate (varies if the clip rate is changed)
Definition: main.h:906
_prefs::perm_audio_reader
boolean perm_audio_reader
Definition: preferences.h:426
FALSE
#define FALSE
Definition: videoplugin.h:60
DEFAULT_AUDIO_CHANS
#define DEFAULT_AUDIO_CHANS
Definition: audio.h:24
weed_reinit_effect
lives_filter_error_t weed_reinit_effect(weed_plant_t *inst, boolean reinit_compound)
Definition: effects-weed.c:1169
FILTER_INFO_REINITED
@ FILTER_INFO_REINITED
values >= 512 are info
Definition: effects-weed.h:40
audio_cache_end
void audio_cache_end(void)
Definition: audio.c:3276
get_audio_file_name
LIVES_GLOBAL_INLINE char * get_audio_file_name(int fnum, boolean opening)
Definition: audio.c:38
lives_alarm_set
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
lives_clip_t::handle
char handle[256]
Definition: main.h:881
_
#define _(String)
Definition: support.h:44
IS_NORMAL_CLIP
#define IS_NORMAL_CLIP(clip)
Definition: main.h:833
_prefs::conserve_space
boolean conserve_space
Definition: preferences.h:183
AUDIO_LOOP_PINGPONG
@ AUDIO_LOOP_PINGPONG
Definition: audio.h:148
WEED_EVENT_IS_AUDIO_FRAME
#define WEED_EVENT_IS_AUDIO_FRAME(event)
Definition: events.h:362
mainwindow::error
boolean error
Definition: mainwindow.h:801
capability::byte_order
int byte_order
Definition: main.h:577
lives_rm
int lives_rm(const char *file)
Definition: utils.c:4395
mainwindow::orignsecs
ticks_t orignsecs
usecs at start of playback - ditto
Definition: mainwindow.h:1001
lives_clip_t::achans
int achans
number of audio channels (0, 1 or 2)
Definition: main.h:907
swab2
LIVES_GLOBAL_INLINE void swab2(const void *from, const void *to, size_t gran)
Definition: machinestate.c:2448
lives_audio_buf_t::buffer16
short ** buffer16
sample data in 16 bit format (or NULL)
Definition: audio.h:110
AFORM_BIG_ENDIAN
#define AFORM_BIG_ENDIAN
Definition: main.h:787
SWAP_L_TO_X
#define SWAP_L_TO_X
local to other
Definition: audio.h:20
mainwindow::aplayer_broken
boolean aplayer_broken
Definition: mainwindow.h:1653
lives_audio_buf_t::in_achans
int in_achans
channels for _filebuffer side
Definition: audio.h:95
get_signed_endian
uint32_t get_signed_endian(boolean is_signed, boolean little_endian)
produce bitmapped value
Definition: utils.c:5408
lives_audio_buf_t::_cachans
int _cachans
current output channels
Definition: audio.h:134
weed_layer_get_audio_length
LIVES_GLOBAL_INLINE int weed_layer_get_audio_length(weed_layer_t *layer)
Definition: colourspace.c:14004
mainwindow::foreign
boolean foreign
for external window capture
Definition: mainwindow.h:824
_prefs::show_dev_opts
boolean show_dev_opts
Definition: preferences.h:463