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