LiVES  3.2.0
jack.c
Go to the documentation of this file.
1 // jack.c
2 // LiVES (lives-exe)
3 // (c) G. Finch 2005 - 2019
4 // Released under the GPL 3 or later
5 // see file ../COPYING for licensing details
6 
7 #include "main.h"
8 #include <jack/jslist.h>
9 #include <jack/control.h>
11 
12 #ifdef ENABLE_JACK
13 #include "callbacks.h"
14 #include "effects.h"
15 #include "effects-weed.h"
16 
17 #define afile mainw->files[jackd->playing_file]
18 
19 static jack_client_t *jack_transport_client;
20 static lives_audio_buf_t *cache_buffer = NULL;
21 
22 static unsigned char *zero_buff = NULL;
23 static size_t zero_buff_count = 0;
24 
25 static boolean seek_err;
26 
27 #ifdef USE_JACKCTL
28 static jackctl_server_t *jackserver = NULL;
29 #endif
30 
31 #define JACK_READ_BYTES 262144
32 
33 static uint8_t jrbuf[JACK_READ_BYTES * 2];
34 
35 static size_t jrb = 0;
36 
37 static off_t fwd_seek_pos = 0;
38 
39 static size_t audio_read_inner(jack_driver_t *jackd, float **in_buffer, int fileno,
40  int nframes, double out_scale, boolean rev_endian, boolean out_unsigned, size_t rbytes);
41 
42 
43 #ifdef ENABLE_JACK_TRANSPORT
44 static boolean jack_playall(livespointer data) {
45  on_playall_activate(NULL, NULL);
46  return FALSE;
47 }
48 #endif
49 
50 // round int a up to next multiple of int b, unless a is already a multiple of b
51 LIVES_LOCAL_INLINE int64_t align_ceilng(int64_t val, int mod) {
52  return (int64_t)((double)(val + mod - 1.) / (double)mod) * (int64_t)mod;
53 }
54 
55 static boolean check_zero_buff(size_t check_size) {
56  if (check_size > zero_buff_count) {
57  zero_buff = (unsigned char *)lives_realloc(zero_buff, check_size);
58  if (zero_buff) {
59  lives_memset(zero_buff + zero_buff_count, 0, check_size - zero_buff_count);
60  zero_buff_count = check_size;
61  return TRUE;
62  }
63  zero_buff_count = 0;
64  return FALSE;
65  }
66  return TRUE;
67 
68 }
69 
70 
71 boolean lives_jack_init(void) {
72  char *jt_client = lives_strdup_printf("LiVES-%d", capable->mainpid);
73  jack_options_t options = JackServerName;
74  jack_status_t status;
75 #ifdef USE_JACKCTL
76  jackctl_driver_t *driver = NULL;
77 #endif
78 
79  const char *server_name = JACK_DEFAULT_SERVER_NAME;
80 
81  jack_transport_client = NULL;
82 
83 #ifdef USE_JACKCTL
85  const JSList *drivers;
86 #ifdef JACK_SYNC_MODE
87  const JSList *params;
88 #endif
89  // start the server
90  jackserver = jackctl_server_create(NULL, NULL);
91  if (!jackserver) {
92  LIVES_ERROR("Could not create jackd server");
93  return FALSE;
94  }
95 
96 #ifdef JACK_SYNC_MODE
97  // list server parameters
98  params = jackctl_server_get_parameters(jackserver);
99  while (params) {
100  jackctl_parameter_t *parameter = (jackctl_parameter_t *)params->data;
101  if (!strcmp(jackctl_parameter_get_name(parameter), "sync")) {
102  union jackctl_parameter_value value;
103  value.b = TRUE;
104  jackctl_parameter_set_value(parameter, &value);
105  break;
106  }
107  params = jack_slist_next(params);
108  }
109 #endif
110 
111  drivers = jackctl_server_get_drivers_list(jackserver);
112  while (drivers) {
113  driver = (jackctl_driver_t *)drivers->data;
114  if (!strcmp(jackctl_driver_get_name(driver), JACK_DRIVER_NAME)) {
115  break;
116  }
117  drivers = jack_slist_next(drivers);
118  }
119  if (!driver) {
120  LIVES_ERROR("Could not find a suitable driver for jack");
121  return FALSE;
122  }
123 
124  if (!jackctl_server_open(jackserver, driver)) {
125  LIVES_ERROR("Could not create the driver for jack");
126  return FALSE;
127  }
128 
129  if (!jackctl_server_start(jackserver)) {
130  LIVES_ERROR("Could not start the jack server");
131  return FALSE;
132  }
133  }
134 
135  mainw->jack_inited = TRUE;
136 
137  options = (jack_options_t)((int)options | (int)JackNoStartServer);
138 
139 #else
140 
142  // TODO: check if still needed
143  lives_unsetenv("JACK_NO_START_SERVER");
144  lives_setenv("JACK_START_SERVER", "1");
145 
146  if (!lives_file_test(prefs->jack_aserver, LIVES_FILE_TEST_EXISTS)) {
147  char *com;
148  char jackd_loc[PATH_MAX];
149  get_location(EXEC_JACKD, jackd_loc, PATH_MAX);
150  if (strlen(jackd_loc)) {
151  com = lives_strdup_printf("echo \"%s -d %s\">\"%s\"", jackd_loc, JACK_DRIVER_NAME, prefs->jack_aserver);
152  lives_system(com, FALSE);
153  lives_free(com);
154  lives_chmod(prefs->jack_aserver, "o+x");
155  }
156  }
157  } else {
158  lives_unsetenv("JACK_START_SERVER");
159  lives_setenv("JACK_NO_START_SERVER", "1");
160  options = (jack_options_t)((int)options | (int)JackNoStartServer);
161  }
162 
163 #endif
164 
165  // startup the transport client now; we will open another later for audio
166  jack_transport_client = jack_client_open(jt_client, options, &status, server_name);
167  lives_free(jt_client);
168 
169  if (!jack_transport_client) return FALSE;
170 
171 #ifdef ENABLE_JACK_TRANSPORT
172  jack_activate(jack_transport_client);
173  jack_set_sync_timeout(jack_transport_client, 5000000); // seems to not work
174  jack_set_sync_callback(jack_transport_client, lives_start_ready_callback, NULL);
175  mainw->jack_trans_poll = TRUE;
176 #else
177  jack_client_close(jack_transport_client);
178  jack_transport_client = NULL;
179 #endif
180 
181  if (status & JackServerStarted) {
182  d_print(_("JACK server started\n"));
183  }
184 
185  return TRUE;
186 }
187 
189 // transport handling
190 
191 
192 ticks_t jack_transport_get_current_ticks(void) {
193 #ifdef ENABLE_JACK_TRANSPORT
194  double val;
195  jack_nframes_t srate;
196  jack_position_t pos;
197 
198  jack_transport_query(jack_transport_client, &pos);
199 
200  srate = jack_get_sample_rate(jack_transport_client);
201  val = (double)pos.frame / (double)srate;
202 
203  if (val > 0.) return val * TICKS_PER_SECOND_DBL;
204 #endif
205  return -1;
206 }
207 
208 
209 #ifdef ENABLE_JACK_TRANSPORT
210 static void jack_transport_check_state(void) {
211  jack_position_t pos;
212  jack_transport_state_t jacktstate;
213 
214  // go away until the app has started up properly
215  if (mainw->go_away) return;
216 
217  if (!(prefs->jack_opts & JACK_OPTS_TRANSPORT_CLIENT)) return;
218 
219  if (!jack_transport_client) return;
220 
221  jacktstate = jack_transport_query(jack_transport_client, &pos);
222 
223  if (mainw->jack_can_start && (jacktstate == JackTransportRolling || jacktstate == JackTransportStarting) &&
227  lives_timer_add_simple(0, jack_playall, NULL);
228  return;
229  }
230 
231  if (jacktstate == JackTransportStopped) {
233  on_stop_activate(NULL, NULL);
234  }
236  }
237 }
238 #endif
239 
240 
241 boolean lives_jack_poll(void) {
242  // data is always NULL
243  // must return TRUE
244 #ifdef ENABLE_JACK_TRANSPORT
245  jack_transport_check_state();
246 #endif
247  return TRUE;
248 }
249 
250 
251 void lives_jack_end(void) {
252 #ifdef ENABLE_JACK_TRANSPORT
253  jack_client_t *client = jack_transport_client;
254 #endif
255  jack_transport_client = NULL; // stop polling transport
256 #ifdef ENABLE_JACK_TRANSPORT
257  if (client) {
258  jack_deactivate(client);
259  jack_client_close(client);
260  }
261 #endif
262 #ifdef USE_JACKCTL
263  if (jackserver) jackctl_server_destroy(jackserver);
264  jackserver = NULL;
265 #endif
266 }
267 
268 
269 void jack_pb_start(double pbtime) {
270  // call this ASAP, then in load_frame_image; we will wait for sync from other clients (and ourself !)
271 #ifdef ENABLE_JACK_TRANSPORT
273  if (pbtime >= 0. && !mainw->jack_can_stop && (prefs->jack_opts & JACK_OPTS_TIMEBASE_LSTART))
274  jack_transport_locate(jack_transport_client, pbtime * jack_get_sample_rate(jack_transport_client));
275  jack_transport_start(jack_transport_client);
276  }
277 #endif
278 }
279 
280 
281 void jack_pb_stop(void) {
282  // call this after pb stops
283 #ifdef ENABLE_JACK_TRANSPORT
284  if (prefs->jack_opts & JACK_OPTS_TRANSPORT_MASTER) jack_transport_stop(jack_transport_client);
285 #endif
286 }
287 
289 // audio
290 
291 static jack_driver_t outdev[JACK_MAX_OUTDEVICES];
292 static jack_driver_t indev[JACK_MAX_INDEVICES];
293 
294 
295 /* not used yet */
296 /*
297  static float set_pulse(float *buf, size_t bufsz, int step) {
298  float *ptr=buf;
299  float *end=buf+bufsz;
300 
301  float tot;
302  int count=0;
303 
304  while (ptr<end) {
305  tot+=*ptr;
306  count++;
307  ptr+=step;
308  }
309  if (count>0) return tot/(float)count;
310  return 0.;
311  }*/
312 
313 
314 void jack_get_rec_avals(jack_driver_t *jackd) {
315  mainw->rec_aclip = jackd->playing_file;
316  if (mainw->rec_aclip != -1) {
317  mainw->rec_aseek = fabs((double)fwd_seek_pos / (double)(afile->achans * afile->asampsize / 8) / (double)afile->arps)
319  mainw->rec_avel = fabs((double)jackd->sample_in_rate / (double)afile->arps) * (double)afile->adirection;
320  }
321 }
322 
323 
324 static void jack_set_rec_avals(jack_driver_t *jackd) {
325  // record direction change (internal)
326  mainw->rec_aclip = jackd->playing_file;
327  if (mainw->rec_aclip != -1) {
328  jack_get_rec_avals(jackd);
329  }
330 }
331 
332 
333 size_t jack_get_buffsize(jack_driver_t *jackd) {
334  if (cache_buffer) return cache_buffer->bytesize;
335  return 0;
336 }
337 
338 
339 static void push_cache_buffer(lives_audio_buf_t *cache_buffer, jack_driver_t *jackd,
340  size_t in_bytes, size_t nframes, double shrink_factor) {
341  // push a cache_buffer for another thread to fill
342  int qnt;
343  if (!cache_buffer) return;
344 
345  qnt = afile->achans * (afile->asampsize >> 3);
346  jackd->seek_pos = align_ceilng(jackd->seek_pos, qnt);
347 
348  if (mainw->ascrap_file > -1 && jackd->playing_file == mainw->ascrap_file) cache_buffer->sequential = TRUE;
349  else cache_buffer->sequential = FALSE;
350 
351  cache_buffer->fileno = jackd->playing_file;
352 
353  cache_buffer->seek = jackd->seek_pos;
354  cache_buffer->bytesize = in_bytes;
355 
356  cache_buffer->in_achans = jackd->num_input_channels;
357  cache_buffer->out_achans = jackd->num_output_channels;
358 
359  cache_buffer->in_asamps = afile->asampsize;
360  cache_buffer->out_asamps = -32;
361 
362  cache_buffer->shrink_factor = shrink_factor;
363 
364  cache_buffer->swap_sign = jackd->usigned;
365  cache_buffer->swap_endian = jackd->reverse_endian ? SWAP_X_TO_L : 0;
366 
367  cache_buffer->samp_space = nframes;
368 
369  cache_buffer->in_interleaf = TRUE;
370  cache_buffer->out_interleaf = FALSE;
371 
372  cache_buffer->operation = LIVES_READ_OPERATION;
373 
375 }
376 
377 
378 LIVES_INLINE lives_audio_buf_t *pop_cache_buffer(void) {
379  // get next available cache_buffer
380  return audio_cache_get_buffer();
381 }
382 
383 
384 static void output_silence(size_t offset, nframes_t nframes, jack_driver_t *jackd, float **out_buffer) {
385  // write nframes silence to all output streams
386  for (int i = 0; i < jackd->num_output_channels; i++) {
387  if (!jackd->is_silent) {
388  sample_silence_dS(out_buffer[i] + offset, nframes);
389  }
391  // audio to be sent to video generator plugins
392  append_to_audio_bufferf(out_buffer[i] + offset, nframes, i);
393  if (i == jackd->num_output_channels - 1) mainw->audio_frame_buffer->samples_filled += nframes;
394  }
395  }
397  // audio to be sent to video playback plugin
398  sample_silence_stream(jackd->num_output_channels, nframes);
399  }
400  if (jackd->astream_fd != -1) {
401  // external streaming
402  size_t rbytes = nframes * jackd->num_output_channels * 2;
403  check_zero_buff(rbytes);
404  audio_stream(zero_buff, rbytes, jackd->astream_fd);
405  }
406  if (!jackd->is_paused) jackd->frames_written += nframes;
407  jackd->real_seek_pos = jackd->seek_pos;
408  if (IS_VALID_CLIP(jackd->playing_file) && jackd->seek_pos < afile->afilesize)
409  afile->aseek_pos = jackd->seek_pos;
410 }
411 
412 
413 static int audio_process(nframes_t nframes, void *arg) {
414  // JACK calls this periodically to get the next audio buffer
415  float *out_buffer[JACK_MAX_OUTPUT_PORTS];
416  jack_driver_t *jackd = (jack_driver_t *)arg;
417  jack_position_t pos;
418  aserver_message_t *msg;
419  int64_t xseek;
420  int new_file;
421  boolean got_cmd = FALSE;
422  boolean from_memory = FALSE;
423  boolean wait_cache_buffer = FALSE;
424  boolean pl_error = FALSE;
425  size_t nbytes, rbytes;
426 
427  int i;
428 #define DEBUG_JACK
429 #ifdef DEBUG_AJACK
430  lives_printerr("nframes %ld, sizeof(float) == %d\n", (int64_t)nframes, sizeof(float));
431 #endif
432 
433  if (!mainw->is_ready || !jackd || (!LIVES_IS_PLAYING && jackd->is_silent && !jackd->msgq)) return 0;
434 
435  /* process one message */
436  while ((msg = (aserver_message_t *)jackd->msgq) != NULL) {
437  got_cmd = TRUE;
438  switch (msg->command) {
440  new_file = atoi((char *)msg->data);
441  if (jackd->playing_file != new_file) {
442  jackd->playing_file = new_file;
443  }
444  jackd->seek_pos = jackd->real_seek_pos = 0;
445  break;
447  jackd->playing_file = -1;
448  jackd->in_use = FALSE;
449  jackd->seek_pos = jackd->real_seek_pos = fwd_seek_pos = 0;
450  break;
452  if (jackd->playing_file < 0) break;
453  xseek = atol((char *)msg->data);
454  xseek = ALIGN_CEIL64(xseek, afile->achans * (afile->asampsize >> 3));
455  if (xseek < 0) xseek = 0;
456  jackd->seek_pos = jackd->real_seek_pos = afile->aseek_pos = xseek;
457  push_cache_buffer(cache_buffer, jackd, 0, 0, 1.);
458  jackd->in_use = TRUE;
459  break;
460  default:
461  jackd->msgq = NULL;
462  msg->data = NULL;
463  }
464 
465  if (msg->next != msg) lives_freep((void **) & (msg->data));
467  jackd->msgq = msg->next;
468  if (jackd->msgq && jackd->msgq->next == jackd->msgq) jackd->msgq->next = NULL;
469  }
470 
471  /* retrieve the buffers for the output ports */
472  for (i = 0; i < jackd->num_output_channels; i++)
473  out_buffer[i] = (float *)jack_port_get_buffer(jackd->output_port[i], nframes);
474 
475  if (got_cmd) {
476  output_silence(0, nframes, jackd, out_buffer);
477  return 0;
478  }
479 
480  fwd_seek_pos = jackd->real_seek_pos = jackd->seek_pos;
481 
482  if (nframes == 0) {
483  return 0;
484  }
485 
487  && jackd->in_use && jackd->playing_file > -1) {
488  //if ((mainw->agen_key == 0 || mainw->agen_needs_reinit || mainw->multitrack) && jackd->in_use) {
489  // if a plugin is generating audio we do not use cache_buffers, otherwise:
490  if (jackd->read_abuf == -1) {
491  // assign local copy from cache_buffers
492  if (!LIVES_IS_PLAYING || (cache_buffer = pop_cache_buffer()) == NULL) {
493  // audio buffer is not ready yet
494  if (!jackd->is_silent) {
495  output_silence(0, nframes, jackd, out_buffer);
496  jackd->is_silent = TRUE;
497  }
498  return 0;
499  }
500  if (cache_buffer->fileno == -1) jackd->playing_file = -1;
501  }
502  if (cache_buffer && cache_buffer->in_achans > 0 && !cache_buffer->is_ready) wait_cache_buffer = TRUE;
503  }
504 
505  jackd->state = jack_transport_query(jackd->client, &pos);
506 
507 #ifdef DEBUG_AJACK
508  lives_printerr("STATE is %d %d\n", jackd->state, jackd->play_when_stopped);
509 #endif
510 
511  /* handle playing state */
512  if (jackd->state == JackTransportRolling || jackd->play_when_stopped) {
513  uint64_t jackFramesAvailable = nframes; /* frames we have left to write to jack */
514  uint64_t inputFramesAvailable; /* frames we have available this loop */
515  uint64_t numFramesToWrite; /* num frames we are writing this loop */
516  int64_t in_frames = 0;
517  uint64_t in_bytes = 0, xin_bytes = 0;
518  float shrink_factor = 1.f;
519  double vol;
520  lives_clip_t *xfile = afile;
521  int qnt = 1;
522  if (IS_VALID_CLIP(jackd->playing_file)) qnt = afile->achans * (afile->asampsize >> 3);
523 
524 #ifdef DEBUG_AJACK
525  lives_printerr("playing... jackFramesAvailable = %ld\n", jackFramesAvailable);
526 #endif
527 
528  jackd->num_calls++;
529 
530  if (!jackd->in_use || ((jackd->playing_file < 0 || jackd->seek_pos < 0.) && jackd->read_abuf < 0
531  && ((mainw->agen_key == 0 && !mainw->agen_needs_reinit)
532  || mainw->multitrack || mainw->preview))
533  || jackd->is_paused) {
534  /* output silence if nothing is being outputted */
535  if (!jackd->is_silent) {
536  output_silence(0, nframes, jackd, out_buffer);
537  jackd->is_silent = TRUE;
538  }
539  return 0;
540  }
541 
542  jackd->is_silent = FALSE;
543 
544  if (!mainw->audio_seek_ready) {
545  if (!mainw->video_seek_ready) {
546  if (!jackd->is_silent) {
547  output_silence(0, nframes, jackd, out_buffer);
548  jackd->is_silent = TRUE;
549  }
550  fwd_seek_pos = jackd->real_seek_pos = jackd->seek_pos;
551  return 0;
552  }
553 
554  // preload the buffer for first read
555  in_bytes = ABS((in_frames = ((double)jackd->sample_in_rate / (double)jackd->sample_out_rate *
556  (double)jackFramesAvailable + ((double)fastrand() / (double)LIVES_MAXUINT64))))
557  * jackd->num_input_channels * jackd->bytes_per_channel;
558 
559  if (cache_buffer) push_cache_buffer(cache_buffer, jackd, in_bytes, nframes, shrink_factor);
562  mainw->fps_mini_measure = 0;
563 
564  pthread_mutex_lock(&mainw->avseek_mutex);
566  pthread_cond_signal(&mainw->avseek_cond);
567  pthread_mutex_unlock(&mainw->avseek_mutex);
568  }
569 
570  if (LIVES_LIKELY(jackFramesAvailable > 0)) {
571  /* (bytes of data) / (2 bytes(16 bits) * X input channels) == frames */
572  if (LIVES_IS_PLAYING && jackd->read_abuf > -1) {
573  // playing back from memory buffers instead of from file
574  // this is used in multitrack
575  from_memory = TRUE;
576 
577  numFramesToWrite = jackFramesAvailable;
578  jackd->frames_written += numFramesToWrite;
579  jackFramesAvailable = 0;
580  } else {
581  boolean eof = FALSE;
582  int playfile = mainw->playing_file;
583  jackd->seek_end = 0;
584  if (mainw->agen_key == 0 && !mainw->agen_needs_reinit && IS_VALID_CLIP(jackd->playing_file)) {
585  if (mainw->playing_sel) {
586  jackd->seek_end = (int64_t)((double)(afile->end - 1.) / afile->fps * afile->arps) * afile->achans
587  * (afile->asampsize / 8);
588  if (jackd->seek_end > afile->afilesize) jackd->seek_end = afile->afilesize;
589  } else {
590  if (!mainw->loop_video) jackd->seek_end = (int64_t)((double)(mainw->play_end - 1.) / afile->fps * afile->arps)
591  * afile->achans * (afile->asampsize / 8);
592  else jackd->seek_end = afile->afilesize;
593  }
594  if (jackd->seek_end > afile->afilesize) jackd->seek_end = afile->afilesize;
595  }
596  if (jackd->seek_end == 0 || ((jackd->playing_file == mainw->ascrap_file && !mainw->preview) && IS_VALID_CLIP(playfile)
597  && mainw->files[playfile]->achans > 0)) jackd->seek_end = INT64_MAX;
598  in_bytes = ABS((in_frames = ((double)jackd->sample_in_rate / (double)jackd->sample_out_rate *
599  (double)jackFramesAvailable + ((double)fastrand() / (double)LIVES_MAXUINT64))))
600  * jackd->num_input_channels * jackd->bytes_per_channel;
601 
602  // update looping mode
605  && ((prefs->audio_opts & AUDIO_OPTS_FOLLOW_CLIPS) || mainw->current_file == jackd->playing_file)
607  && mainw->agen_key == 0 && !mainw->agen_needs_reinit)
608  jackd->loop = AUDIO_LOOP_PINGPONG;
609  else jackd->loop = AUDIO_LOOP_FORWARD;
610  } else {
611  jackd->loop = AUDIO_LOOP_NONE;
612  }
613 
614  if (cache_buffer) eof = cache_buffer->eof;
615 
616  if ((shrink_factor = (float)in_frames / (float)jackFramesAvailable) >= 0.f) {
617  jackd->seek_pos += in_bytes;
618  if (jackd->playing_file != mainw->ascrap_file) {
619  if (eof || (jackd->seek_pos >= jackd->seek_end && !afile->opening)) {
620  if (jackd->loop == AUDIO_LOOP_NONE) {
621  if (*jackd->whentostop == STOP_ON_AUD_END) {
622  *jackd->cancelled = CANCEL_AUD_END;
623  jackd->in_use = FALSE;
624  }
625  in_bytes = 0;
626  } else {
627  if (jackd->loop == AUDIO_LOOP_PINGPONG && ((jackd->playing_file != mainw->playing_file)
629  jackd->sample_in_rate = -jackd->sample_in_rate;
630  afile->adirection = -afile->adirection;
631  jackd->seek_pos -= (jackd->seek_pos - jackd->seek_end);
632  } else {
633  if (mainw->playing_sel) {
634  fwd_seek_pos = jackd->seek_pos = jackd->real_seek_pos
635  = (int64_t)((double)(afile->start - 1.) / afile->fps * afile->arps)
636  * afile->achans * (afile->asampsize / 8);
637  } else fwd_seek_pos = jackd->seek_pos = jackd->real_seek_pos = 0;
638  if (mainw->record && !mainw->record_paused) jack_set_rec_avals(jackd);
639  // *INDENT-OFF*
640  }}}}
641  // *INDENT-ON*
642  } else {
643  // reverse playback
644  off_t seek_start = (mainw->playing_sel ?
645  (int64_t)((double)(afile->start - 1.) / afile->fps * afile->arps)
646  * afile->achans * (afile->asampsize / 8) : 0);
647  seek_start = ALIGN_CEIL64(seek_start - qnt, qnt);
648 
649  if ((jackd->seek_pos -= in_bytes) < seek_start) {
650  // reached beginning backwards
651  if (jackd->playing_file != mainw->ascrap_file) {
652  if (jackd->loop == AUDIO_LOOP_NONE) {
653  if (*jackd->whentostop == STOP_ON_AUD_END) {
654  *jackd->cancelled = CANCEL_AUD_END;
655  }
656  jackd->in_use = FALSE;
657  } else {
658  if (jackd->loop == AUDIO_LOOP_PINGPONG && ((jackd->playing_file != mainw->playing_file)
660  jackd->sample_in_rate = -jackd->sample_in_rate;
661  afile->adirection = -afile->adirection;
662  shrink_factor = -shrink_factor;
663  jackd->seek_pos = seek_start;
664  } else {
665  jackd->seek_pos += jackd->seek_end;
666  if (jackd->seek_pos > jackd->seek_end - in_bytes) jackd->seek_pos = jackd->seek_end - in_bytes;
667  }
668  }
669  fwd_seek_pos = jackd->real_seek_pos = jackd->seek_pos;
670  if (mainw->record && !mainw->record_paused) jack_set_rec_avals(jackd);
671  }
672  }
673  }
674 
675  if (jackd->mute || !cache_buffer ||
676  (in_bytes == 0 &&
678  if (!mainw->multitrack && cache_buffer && !wait_cache_buffer
679  && ((mainw->agen_key == 0 && !mainw->agen_needs_reinit)
680  || mainw->preview)) {
681  push_cache_buffer(cache_buffer, jackd, in_bytes, nframes, shrink_factor);
682  }
683  output_silence(0, nframes, jackd, out_buffer);
684  return 0;
685  } else {
686  xin_bytes = 0;
687  }
688  if (mainw->agen_key != 0 && !mainw->multitrack && !mainw->preview) {
689  // how much audio do we want to pull from any generator ?
690  in_bytes = jackFramesAvailable * jackd->num_output_channels * 4;
691  xin_bytes = in_bytes;
692  }
693 
694  if (!jackd->in_use || in_bytes == 0) {
695  // reached end of audio with no looping
696  output_silence(0, nframes, jackd, out_buffer);
697 
698  jackd->is_silent = TRUE;
699 
700  if (jackd->seek_pos < 0. && jackd->playing_file > -1 && xfile) {
701  jackd->seek_pos += nframes * xfile->achans * xfile->asampsize / 8;
702  }
703  return 0;
704  }
705 
707  inputFramesAvailable = cache_buffer->samp_space;
708  else inputFramesAvailable = jackFramesAvailable;
709 
710 #ifdef DEBUG_AJACK
711  lives_printerr("%d inputFramesAvailable == %ld, %ld %ld,jackFramesAvailable == %ld\n", inputFramesAvailable,
712  in_frames, jackd->sample_in_rate, jackd->sample_out_rate, jackFramesAvailable);
713 #endif
714 
715  /* write as many bytes as we have space remaining, or as much as we have data to write */
716  numFramesToWrite = MIN(jackFramesAvailable, inputFramesAvailable);
717 
718 #ifdef DEBUG_AJACK
719  lives_printerr("nframes == %d, jackFramesAvailable == %ld,\n\tjackd->num_input_channels == %ld,"
720  "jackd->num_output_channels == %ld, nf2w %ld, in_bytes %d, sf %.8f\n",
721  nframes, jackFramesAvailable, jackd->num_input_channels, jackd->num_output_channels,
722  numFramesToWrite, in_bytes, shrink_factor);
723 #endif
724  jackd->frames_written += numFramesToWrite;
725  jackFramesAvailable -= numFramesToWrite; /* take away what was written */
726 
727 #ifdef DEBUG_AJACK
728  lives_printerr("jackFramesAvailable == %ld\n", jackFramesAvailable);
729 #endif
730  }
731 
732  // playback from memory or file
734 
735  if (numFramesToWrite > 0) {
736  if (!from_memory) {
737  // if (((int)(jackd->num_calls/100.))*100==jackd->num_calls) if (mainw->soft_debug) g_print("audio pip\n");
738  if ((mainw->agen_key != 0 || mainw->agen_needs_reinit || cache_buffer->bufferf) && !mainw->preview &&
739  !jackd->mute) { // TODO - try buffer16 instead of bufferf
740  float *fbuffer = NULL;
741 
742  if (!mainw->preview && !mainw->multitrack && (mainw->agen_key != 0 || mainw->agen_needs_reinit)) {
743  // audio generated from plugin
744  if (mainw->agen_needs_reinit) pl_error = TRUE;
745  else {
746  if (!get_audio_from_plugin(out_buffer, jackd->num_output_channels,
747  jackd->sample_out_rate, numFramesToWrite, TRUE)) {
748  pl_error = TRUE;
749  }
750  }
751 
752  // get back non-interleaved float fbuffer; rate and channels should match
753  if (pl_error) {
754  // error in plugin, put silence
755  output_silence(0, numFramesToWrite, jackd, out_buffer);
756  } else {
757  for (i = 0; i < jackd->num_output_channels; i++) {
758  // push non-interleaved audio in fbuffer to jack
760  // we will push the pre-effected audio to any audio reactive generators
761  append_to_audio_bufferf(out_buffer[i], numFramesToWrite, i);
762  if (i == jackd->num_output_channels - 1) mainw->audio_frame_buffer->samples_filled += numFramesToWrite;
763  }
764  }
765  }
766  //}
767  if (!pl_error && has_audio_filters(AF_TYPE_ANY)) {
768  float **xfltbuf;
769  ticks_t tc = mainw->currticks;
770  // apply inplace any effects with audio in_channels, result goes to jack
772  weed_layer_set_audio_data(layer, out_buffer, jackd->sample_out_rate,
773  jackd->num_output_channels, numFramesToWrite);
774  weed_set_boolean_value(layer, WEED_LEAF_HOST_KEEP_ADATA, WEED_TRUE);
776  xfltbuf = weed_layer_get_audio_data(layer, NULL);
777  for (i = 0; i < jackd->num_output_channels; i++) {
778  if (xfltbuf[i] != out_buffer[i]) {
779  lives_memcpy(out_buffer[i], xfltbuf[i], numFramesToWrite * sizeof(float));
780  lives_free(xfltbuf[i]);
781  }
782  }
783  lives_free(xfltbuf);
784  weed_layer_set_audio_data(layer, NULL, 0, 0, 0);
785  weed_layer_free(layer);
786  }
787 
788  pthread_mutex_lock(&mainw->vpp_stream_mutex);
790  (*mainw->vpp->render_audio_frame_float)(out_buffer, numFramesToWrite);
791  }
792  pthread_mutex_unlock(&mainw->vpp_stream_mutex);
793 
794  if (mainw->record && mainw->ascrap_file != -1 && mainw->playing_file > 0) {
795  // if recording we will save this audio fragment
796  int out_unsigned = mainw->files[mainw->ascrap_file]->signed_endian & AFORM_UNSIGNED;
797  rbytes = numFramesToWrite * mainw->files[mainw->ascrap_file]->achans *
799 
800  rbytes = audio_read_inner(jackd, out_buffer, mainw->ascrap_file, numFramesToWrite, 1.0,
802  out_unsigned, rbytes);
803 
804  mainw->files[mainw->ascrap_file]->aseek_pos += rbytes;
805  }
806  } else {
807  // audio from a file
808  if (wait_cache_buffer) {
809  while (!cache_buffer->is_ready && !cache_buffer->die) {
810  lives_usleep(prefs->sleep_time);
811  }
812  wait_cache_buffer = FALSE;
813  }
814 
815  pthread_mutex_lock(&mainw->cache_buffer_mutex);
816  if (!cache_buffer->die) {
817  // push audio from cache_buffer to jack
818  for (i = 0; i < jackd->num_output_channels; i++) {
819  jackd->abs_maxvol_heard = sample_move_d16_float(out_buffer[i], cache_buffer->buffer16[0] + i, numFramesToWrite,
820  jackd->num_input_channels, afile->signed_endian & AFORM_UNSIGNED, FALSE, vol);
821 
823  // we will push the pre-effected audio to any audio reactive generators
824  append_to_audio_bufferf(out_buffer[i], numFramesToWrite, i);
825  if (i == jackd->num_output_channels - 1) mainw->audio_frame_buffer->samples_filled += numFramesToWrite;
826  }
827  }
828  pthread_mutex_unlock(&mainw->cache_buffer_mutex);
829 
830  if (has_audio_filters(AF_TYPE_ANY) && jackd->playing_file != mainw->ascrap_file) {
831  float **xfltbuf;
832  ticks_t tc = mainw->currticks;
833  // apply inplace any effects with audio in_channels
835  weed_set_voidptr_array(layer, WEED_LEAF_AUDIO_DATA, jackd->num_output_channels, (void **)out_buffer);
836  weed_layer_set_audio_data(layer, out_buffer, jackd->sample_out_rate,
837  jackd->num_output_channels, numFramesToWrite);
838  weed_set_boolean_value(layer, WEED_LEAF_HOST_KEEP_ADATA, WEED_TRUE);
840  xfltbuf = weed_layer_get_audio_data(layer, NULL);
841  for (i = 0; i < jackd->num_output_channels; i++) {
842  if (xfltbuf[i] != out_buffer[i]) {
843  lives_memcpy(out_buffer[i], xfltbuf[i], numFramesToWrite * sizeof(float));
844  lives_free(xfltbuf[i]);
845  }
846  }
847  lives_free(xfltbuf);
848  weed_layer_set_audio_data(layer, NULL, 0, 0, 0);
849  weed_layer_free(layer);
850  }
851 
852  pthread_mutex_lock(&mainw->vpp_stream_mutex);
854  (*mainw->vpp->render_audio_frame_float)(out_buffer, numFramesToWrite);
855  }
856  pthread_mutex_unlock(&mainw->vpp_stream_mutex);
857  } else {
858  // cache_buffer->die == TRUE
859  pthread_mutex_unlock(&mainw->cache_buffer_mutex);
860  output_silence(0, numFramesToWrite, jackd, out_buffer);
861  }
862  }
863 
864  if (jackd->astream_fd != -1) {
865  // audio streaming if enabled
866  unsigned char *xbuf;
867 
868  nbytes = numFramesToWrite * jackd->num_output_channels * 4;
869  rbytes = numFramesToWrite * jackd->num_output_channels * 2;
870 
871  if (pl_error) {
872  // generator plugin error - output silence
873  check_zero_buff(rbytes);
874  audio_stream(zero_buff, rbytes, jackd->astream_fd);
875  } else {
876  if ((mainw->agen_key == 0 && !mainw->agen_needs_reinit) && !mainw->multitrack && !mainw->preview)
877  xbuf = (unsigned char *)cache_buffer->buffer16[0];
878  else {
879  // plugin is generating and we are streaming: convert fbuffer to s16
880  float **fp = (float **)lives_malloc(jackd->num_output_channels * sizeof(float *));
881  for (i = 0; i < jackd->num_output_channels; i++) {
882  fp[i] = fbuffer + i;
883  }
884  xbuf = (unsigned char *)lives_malloc(nbytes * jackd->num_output_channels);
885  sample_move_float_int((void *)xbuf, fp, numFramesToWrite, 1.0,
886  jackd->num_output_channels, 16, 0, TRUE, TRUE, 1.0);
887  }
888 
889  if (jackd->num_output_channels != 2) {
890  // need to remap channels to stereo (assumed for now)
891  size_t bysize = 4, tsize = 0;
892  unsigned char *inbuf, *oinbuf = NULL;
893 
895  inbuf = (unsigned char *)cache_buffer->buffer16[0];
896  else oinbuf = inbuf = xbuf;
897 
898  xbuf = (unsigned char *)lives_malloc(nbytes);
899  if (!xbuf) {
900  // external streaming
901  rbytes = numFramesToWrite * jackd->num_output_channels * 2;
902  if (check_zero_buff(rbytes))
903  audio_stream(zero_buff, rbytes, jackd->astream_fd);
904  return 0;
905  }
906  if (jackd->num_output_channels == 1) bysize = 2;
907  while (nbytes > 0) {
908  lives_memcpy(xbuf + tsize, inbuf, bysize);
909  tsize += bysize;
910  nbytes -= bysize;
911  if (bysize == 2) {
912  // duplicate mono channel
913  lives_memcpy(xbuf + tsize, inbuf, bysize);
914  tsize += bysize;
915  nbytes -= bysize;
916  inbuf += bysize;
917  } else {
918  // or skip extra channels
919  inbuf += jackd->num_output_channels * 4;
920  }
921  }
922  nbytes = numFramesToWrite * jackd->num_output_channels * 4;
923  lives_freep((void **)&oinbuf);
924  }
925 
926  // push to stream
927  rbytes = numFramesToWrite * jackd->num_output_channels * 2;
928  audio_stream(xbuf, rbytes, jackd->astream_fd);
929  if (((mainw->agen_key != 0 || mainw->agen_needs_reinit) && !mainw->multitrack
930  && !mainw->preview) || xbuf != (unsigned char *)cache_buffer->buffer16[0]) lives_free(xbuf);
931  }
932  } // end audio stream
933  lives_freep((void **)&fbuffer);
934  } else {
935  // no generator plugin, but audio is muted
936  output_silence(0, numFramesToWrite, jackd, out_buffer);
937  }
938  } else {
939  // cached from files - multitrack mode
940  if (jackd->read_abuf > -1 && !jackd->mute) {
941  sample_move_abuf_float(out_buffer, jackd->num_output_channels, nframes, jackd->sample_out_rate, vol);
942 
943  if (jackd->astream_fd != -1) {
944  // audio streaming if enabled
945  unsigned char *xbuf = (unsigned char *)out_buffer;
946  nbytes = numFramesToWrite * jackd->num_output_channels * 4;
947 
948  if (jackd->num_output_channels != 2) {
949  // need to remap channels to stereo (assumed for now)
950  size_t bysize = 4, tsize = 0;
951  unsigned char *inbuf = (unsigned char *)out_buffer;
952  xbuf = (unsigned char *)lives_malloc(nbytes);
953  if (!xbuf) {
954  output_silence(0, numFramesToWrite, jackd, out_buffer);
955  return 0;
956  }
957 
958  if (jackd->num_output_channels == 1) bysize = 2;
959  while (nbytes > 0) {
960  lives_memcpy(xbuf + tsize, inbuf, bysize);
961  tsize += bysize;
962  nbytes -= bysize;
963  if (bysize == 2) {
964  // duplicate mono channel
965  lives_memcpy(xbuf + tsize, inbuf, bysize);
966  tsize += bysize;
967  nbytes -= bysize;
968  inbuf += bysize;
969  } else {
970  // or skip extra channels
971  inbuf += jackd->num_output_channels * 4;
972  }
973  }
974  nbytes = numFramesToWrite * jackd->num_output_channels * 2;
975  }
976  rbytes = numFramesToWrite * jackd->num_output_channels * 2;
977  audio_stream(xbuf, rbytes, jackd->astream_fd);
978  if (xbuf != (unsigned char *)out_buffer) lives_free(xbuf);
979  }
980  } else {
981  // muted or no audio available
982  output_silence(0, numFramesToWrite, jackd, out_buffer);
983  }
984  }
985  } else {
986  // no input frames left, pad with silence
987  output_silence(nframes - jackFramesAvailable, jackFramesAvailable, jackd, out_buffer);
988  jackFramesAvailable = 0;
989  }
990  }
991 
992  if (!from_memory) {
993  // push the cache_buffer to be filled
994  if (!mainw->multitrack && !wait_cache_buffer && ((mainw->agen_key == 0 && ! mainw->agen_needs_reinit)
995  || mainw->preview)) {
996  push_cache_buffer(cache_buffer, jackd, in_bytes, nframes, shrink_factor);
997  }
1000  if (shrink_factor > 0.) jackd->seek_pos += xin_bytes / 4 * jackd->bytes_per_channel;
1001  }
1002 
1003  /* jackd->jack_jack[0]=set_jack(out_buffer[0],jack->buffer_size,8);
1004  if (jackd->num_output_channels>1) {
1005  jackd->jack_jack[1]=set_jack(out_buffer[1],jackd->buffer_size,8);
1006  }
1007  else jackd->jack_jack[1]=jackd->jack_jack[0];
1008  */
1009 
1010  if (jackFramesAvailable > 0) {
1011 #ifdef DEBUG_AJACK
1012  ++mainw->uflow_count;
1013  lives_printerr("buffer underrun of %ld frames\n", jackFramesAvailable);
1014 #endif
1015  output_silence(nframes - jackFramesAvailable, jackFramesAvailable, jackd, out_buffer);
1016  }
1017  } else if (jackd->state == JackTransportStarting || jackd->state == JackTransportStopped ||
1018  jackd->state == JackTClosed || jackd->state == JackTReset) {
1019 #ifdef DEBUG_AJACK
1020  lives_printerr("PAUSED or STOPPED or CLOSED, outputting silence\n");
1021 #endif
1022 
1023  /* output silence if nothing is being outputted */
1024  output_silence(0, nframes, jackd, out_buffer);
1025  jackd->is_silent = TRUE;
1026 
1027  /* if we were told to reset then zero out some variables */
1028  /* and transition to STOPPED */
1029  if (jackd->state == JackTReset) {
1030  jackd->state = (jack_transport_state_t)JackTStopped; /* transition to STOPPED */
1031  }
1032  }
1033 
1034 #ifdef DEBUG_AJACK
1035  lives_printerr("done\n");
1036 #endif
1037 
1038  return 0;
1039 }
1040 
1041 
1042 int lives_start_ready_callback(jack_transport_state_t state, jack_position_t *pos, void *arg) {
1043  // mainw->video_seek_ready is generally FALSE
1044  // if we are not playing, the transport poll should start playing which will set set
1045  // mainw->video_seek_ready to true, as soon as the video is at the right place
1046 
1047  // if we are playing, we set mainw->scratch
1048  // this will either force a resync of audio in free playback
1049  // or reset the event_list position in multitrack playback
1050 
1052 
1053  // go away until the app has started up properly
1054  if (mainw->go_away) {
1055  if (state == JackTransportStopped) mainw->jack_can_start = TRUE;
1057  return TRUE;
1058  }
1059 
1060  if (!(prefs->jack_opts & JACK_OPTS_TRANSPORT_CLIENT)) return TRUE;
1061  if (!jack_transport_client) return TRUE;
1062 
1063  if (!LIVES_IS_PLAYING && state == JackTransportStopped) {
1065  double trtime = (double)jack_transport_get_current_ticks() / TICKS_PER_SECOND_DBL;
1066  if (!mainw->multitrack) {
1067 #ifndef ENABLE_GIW_3
1068  lives_ruler_set_value(LIVES_RULER(mainw->hruler), x);
1070 #else
1071  lives_adjustment_set_value(giw_timeline_get_adjustment(GIW_TIMELINE(mainw->hruler)), trtime);
1072 #endif
1073  } else mt_tl_move(mainw->multitrack, trtime);
1074  }
1075  return TRUE;
1076  }
1077 
1078  if (state != JackTransportStarting) return TRUE;
1079 
1081  // trigger audio resync
1083  }
1084 
1086 }
1087 
1088 
1089 size_t jack_flush_read_data(size_t rbytes, void *data) {
1090  // rbytes here is how many bytes to write
1091  size_t bytes = 0;
1092 
1093  if (!data) {
1094  // final flush at end
1095  data = jrbuf;
1096  rbytes = jrb;
1097  }
1098 
1099  jrb = 0;
1100 
1101  if (!THREADVAR(bad_aud_file)) {
1102  // use write not use lives_write - because of potential threading issues
1103  bytes = write(mainw->aud_rec_fd, data, rbytes);
1104  if (bytes > 0) {
1105  uint64_t chk = (mainw->aud_data_written & AUD_WRITE_CHECK);
1106  mainw->aud_data_written += bytes;
1107  if (mainw->ascrap_file != -1 && mainw->files[mainw->ascrap_file] &&
1109  add_to_ascrap_mb(bytes);
1111  }
1112  if (bytes < rbytes) THREADVAR(bad_aud_file) = filename_from_fd(NULL, mainw->aud_rec_fd);
1113  }
1114  return bytes;
1115 }
1116 
1117 
1118 static size_t audio_read_inner(jack_driver_t *jackd, float **in_buffer, int ofileno, int nframes,
1119  double out_scale, boolean rev_endian, boolean out_unsigned, size_t rbytes) {
1120 
1121  // read audio, buffer it and when we have enough, write it to aud_rec_fd
1122 
1123  int frames_out;
1124 
1125  size_t bytes_out;
1126 
1127  void *holding_buff;
1128 
1129  lives_clip_t *ofile = mainw->files[ofileno];
1130 
1131  frames_out = (int64_t)((double)nframes / out_scale + 1.);
1132  bytes_out = frames_out * ofile->achans * (ofile->asampsize >> 3);
1133 
1134  holding_buff = lives_malloc(bytes_out);
1135  if (!holding_buff) return 0;
1136 
1137  frames_out = sample_move_float_int(holding_buff, in_buffer, nframes, out_scale, ofile->achans,
1138  ofile->asampsize, out_unsigned, rev_endian, FALSE, 1.);
1139 
1140  if (mainw->rec_samples > 0) {
1141  if (frames_out > mainw->rec_samples) frames_out = mainw->rec_samples;
1142  mainw->rec_samples -= frames_out;
1143  }
1144 
1145  rbytes = frames_out * (ofile->asampsize / 8) * ofile->achans;
1146  jrb += rbytes;
1147 
1148  // write to jrbuf
1149  if (jrb < JACK_READ_BYTES && (mainw->rec_samples == -1 || frames_out < mainw->rec_samples)) {
1150  // buffer until we have enough
1151  lives_memcpy(&jrbuf[jrb - rbytes], holding_buff, rbytes);
1152  return rbytes;
1153  }
1154 
1155  // if we have enough, flush it to file
1156  if (jrb <= JACK_READ_BYTES * 2) {
1157  lives_memcpy(&jrbuf[jrb - rbytes], holding_buff, rbytes);
1158  jack_flush_read_data(jrb, jrbuf);
1159  } else {
1160  if (jrb > rbytes) jack_flush_read_data(jrb - rbytes, jrbuf);
1161  jack_flush_read_data(rbytes, holding_buff);
1162  }
1163 
1164  lives_free(holding_buff);
1165 
1166  return rbytes;
1167 }
1168 
1169 
1170 static int audio_read(nframes_t nframes, void *arg) {
1171  // read nframes from jack buffer, and then write to mainw->aud_rec_fd
1172 
1173  // this is the jack callback for when we are recording audio
1174 
1175  // for AUDIO_SRC_EXT, jackd->playing_file is actually the file we write audio to
1176  // which can be either the ascrap file (for playback recording), or a normal file (for voiceovers), or -1 (just listening)
1177 
1178  // TODO - get abs_maxvol_heard
1179 
1180  jack_driver_t *jackd = (jack_driver_t *)arg;
1181  float *in_buffer[jackd->num_input_channels];
1182  float out_scale;
1183  float tval = 0;
1184  int out_unsigned = AFORM_UNSIGNED;
1185  int i;
1186 
1187  size_t rbytes = 0;
1188 
1189  if (!jackd->in_use) return 0;
1190 
1191  if (mainw->playing_file < 0 && prefs->audio_src == AUDIO_SRC_EXT) return 0;
1192 
1193  if (mainw->effects_paused) return 0; // pause during record
1194 
1195  if (mainw->rec_samples == 0) return 0; // wrote enough already, return until main thread stop
1196 
1197  for (i = 0; i < jackd->num_input_channels; i++) {
1198  in_buffer[i] = (float *) jack_port_get_buffer(jackd->input_port[i], nframes);
1199  tval += *in_buffer[i];
1200  }
1201 
1202  if (!mainw->fs && !mainw->faded && !mainw->multitrack && mainw->ext_audio_mon)
1203  lives_toggle_tool_button_set_active(LIVES_TOGGLE_TOOL_BUTTON(mainw->ext_audio_mon), tval > 0.);
1204 
1205  jackd->frames_written += nframes;
1206 
1207  if (prefs->audio_src == AUDIO_SRC_EXT && (jackd->playing_file == -1 || jackd->playing_file == mainw->ascrap_file)) {
1208  // TODO - dont apply filters when doing ext window grab, or voiceover
1209 
1210  // in this case we read external audio, but maybe not record it
1211  // we may wish to analyse the audio for example, or push it to a video generator
1212 
1213  if (has_audio_filters(AF_TYPE_A)) { // AF_TYPE_A are Analyser filters (audio in but no audio channels out)
1214  ticks_t tc = mainw->currticks;
1216 
1218  // if we have audio triggered gens., push audio to it
1219  for (i = 0; i < jackd->num_input_channels; i++) {
1220  append_to_audio_bufferf(in_buffer[i], nframes, i);
1221  }
1223  }
1224  // apply any audio effects with in_channels and no out_channels
1225  weed_layer_set_audio_data(layer, in_buffer, jackd->sample_in_rate, jackd->num_output_channels, nframes);
1226  weed_apply_audio_effects_rt(layer, tc, TRUE, TRUE);
1227  weed_layer_set_audio_data(layer, NULL, 0, 0, 0);
1228  weed_layer_free(layer);
1229  }
1230  }
1231 
1232  pthread_mutex_lock(&mainw->audio_filewriteend_mutex);
1233 
1234  if (mainw->record && mainw->record_paused && jrb > 0) {
1235  jack_flush_read_data(jrb, jrbuf);
1236  }
1237 
1238  if (jackd->playing_file == -1 || (mainw->record && mainw->record_paused)) {
1239  jrb = 0;
1240  pthread_mutex_unlock(&mainw->audio_filewriteend_mutex);
1241  return 0;
1242  }
1243 
1244  if (!IS_VALID_CLIP(jackd->playing_file)) out_scale = 1.0; // just listening
1245  else {
1246  out_scale = (float)afile->arate / (float)jackd->sample_in_rate; // recording to ascrap_file
1247  out_unsigned = afile->signed_endian & AFORM_UNSIGNED;
1248  }
1249 
1250  rbytes = audio_read_inner(jackd, in_buffer, jackd->playing_file, nframes, out_scale, jackd->reverse_endian,
1251  out_unsigned, rbytes);
1252 
1254  mainw->files[mainw->playing_file]->aseek_pos += rbytes;
1255  if (mainw->ascrap_file != -1 && !mainw->record_paused) mainw->files[mainw->ascrap_file]->aseek_pos += rbytes;
1256 
1257  jackd->seek_pos += rbytes;
1258 
1259  pthread_mutex_unlock(&mainw->audio_filewriteend_mutex);
1260 
1261  if (mainw->rec_samples == 0 && mainw->cancelled == CANCEL_NONE) mainw->cancelled = CANCEL_KEEP; // we wrote the required #
1262 
1263  return 0;
1264 }
1265 
1266 
1267 int jack_get_srate(nframes_t nframes, void *arg) {
1268  //lives_printerr("the sample rate is now %ld/sec\n", (int64_t)nframes);
1269  // TODO: reset timebase
1270  return 0;
1271 }
1272 
1273 
1274 void jack_shutdown(void *arg) {
1275  jack_driver_t *jackd = (jack_driver_t *)arg;
1276 
1277  jackd->client = NULL; /* reset client */
1278  jackd->jackd_died = TRUE;
1279  jackd->msgq = NULL;
1280 
1281  lives_printerr("jack shutdown, setting client to 0 and jackd_died to true\n");
1282  lives_printerr("trying to reconnect right now\n");
1283 
1285 
1286  jack_audio_init();
1287 
1288  // TODO: init reader as well
1289 
1290  mainw->jackd = jack_get_driver(0, TRUE);
1291  mainw->jackd->msgq = NULL;
1292 
1293  if (mainw->jackd->playing_file != -1 && afile)
1294  jack_audio_seek_bytes(mainw->jackd, mainw->jackd->seek_pos, afile); // at least re-seek to the right place
1295 }
1296 
1297 
1298 static void jack_reset_driver(jack_driver_t *jackd) {
1299  // does nothing ?
1300  jackd->state = (jack_transport_state_t)JackTReset;
1301 }
1302 
1303 
1304 void jack_close_device(jack_driver_t *jackd) {
1305  //int i;
1306 
1307  //lives_printerr("closing the jack client thread\n");
1308  if (jackd->client) {
1309  jack_deactivate(jackd->client); /* supposed to help the jack_client_close() to succeed */
1310  //lives_printerr("after jack_deactivate()\n");
1311  jack_client_close(jackd->client);
1312  }
1313 
1314  jack_reset_driver(jackd);
1315  jackd->client = NULL;
1316 
1317  jackd->is_active = FALSE;
1318 
1319  /* free up the port strings */
1320  //lives_printerr("freeing up port strings\n");
1321  // TODO: check this
1322  /* if (jackd->jack_port_name_count > 1) { */
1323  /* for (i = 0; i < jackd->jack_port_name_count; i++) free(jackd->jack_port_name[i]); */
1324  /* free(jackd->jack_port_name); */
1325  /* } */
1326 }
1327 
1328 
1329 static void jack_error_func(const char *desc) {
1330  lives_printerr("Jack audio error %s\n", desc);
1331 }
1332 
1333 
1334 // create a new client but don't connect the ports yet
1335 boolean jack_create_client_writer(jack_driver_t *jackd) {
1336  const char *client_name = "LiVES_audio_out";
1337  const char *server_name = JACK_DEFAULT_SERVER_NAME;
1338  jack_options_t options = (jack_options_t)((int)JackServerName | (int)JackNoStartServer);
1339  jack_status_t status;
1340  boolean needs_sigs = FALSE;
1341  lives_alarm_t alarm_handle;
1342  int i;
1343 
1344  if (mainw->aplayer_broken) return FALSE;
1345 
1346  jackd->is_active = FALSE;
1347 
1348  /* set up an error handler */
1349  jack_set_error_function(jack_error_func);
1350  jackd->client = NULL;
1351 
1352  if (!mainw->signals_deferred) {
1353  // try to handle crashes in jack_client_open()
1355  needs_sigs = TRUE;
1356  mainw->crash_possible = 1;
1357  }
1358 
1359  alarm_handle = lives_alarm_set(LIVES_SHORT_TIMEOUT);
1360  while (!jackd->client && lives_alarm_check(alarm_handle) > 0) {
1361  jackd->client = jack_client_open(client_name, options, &status, server_name);
1362  lives_usleep(prefs->sleep_time);
1363  }
1364  lives_alarm_clear(alarm_handle);
1365 
1366  if (needs_sigs) {
1368  mainw->crash_possible = 0;
1369  }
1370 
1371  if (!jackd->client) {
1372  lives_printerr("jack_client_open() failed, status = 0x%2.0x\n", status);
1373  if (status & JackServerFailed) {
1374  d_print(_("Unable to connect to JACK server\n"));
1375  }
1376  return FALSE;
1377  }
1378 
1379  if (status & JackNameNotUnique) {
1380  client_name = jack_get_client_name(jackd->client);
1381  lives_printerr("unique name `%s' assigned\n", client_name);
1382  }
1383 
1384  jackd->sample_out_rate = jackd->sample_in_rate = jack_get_sample_rate(jackd->client);
1385 
1386  //lives_printerr (lives_strdup_printf("engine sample rate: %ld\n",jackd->sample_rate));
1387 
1388  for (i = 0; i < jackd->num_output_channels; i++) {
1389  char portname[32];
1390  lives_snprintf(portname, 32, "out_%d", i);
1391 
1392 #ifdef DEBUG_JACK_PORTS
1393  lives_printerr("output port %d is named '%s'\n", i, portname);
1394 #endif
1395 
1396  jackd->output_port[i] = jack_port_register(jackd->client, portname,
1397  JACK_DEFAULT_AUDIO_TYPE,
1398  JackPortIsOutput | JackPortIsTerminal,
1399  0);
1400 
1401  if (!jackd->output_port[i]) {
1402  lives_printerr("nay more JACK output ports available\n");
1403  return FALSE;
1404  }
1405  jackd->out_chans_available++;
1406  }
1407 
1408  /* tell the JACK server to call `srate()' whenever
1409  the sample rate of the system changes. */
1410  jack_set_sample_rate_callback(jackd->client, jack_get_srate, jackd);
1411 
1412  /* tell the JACK server to call `jack_shutdown()' if
1413  it ever shuts down, either entirely, or if it
1414  just decides to stop calling us. */
1415  jack_on_shutdown(jackd->client, jack_shutdown, jackd);
1416 
1417  jack_set_process_callback((jack_client_t *)jackd->client, audio_process, jackd);
1418 
1419  return TRUE;
1420 }
1421 
1422 
1423 boolean jack_create_client_reader(jack_driver_t *jackd) {
1424  // open a device to read audio from jack
1425  const char *client_name = "LiVES_audio_in";
1426  const char *server_name = JACK_DEFAULT_SERVER_NAME;
1427  jack_options_t options = (jack_options_t)((int)JackServerName | (int)JackNoStartServer);
1428  jack_status_t status;
1429  int i;
1430 
1431  jackd->is_active = FALSE;
1432 
1433  /* set up an error handler */
1434  jack_set_error_function(jack_error_func);
1435  jackd->client = NULL;
1436 
1437  // create a client and attach it to the server
1438  while (!jackd->client)
1439  jackd->client = jack_client_open(client_name, options, &status, server_name);
1440 
1441  if (!jackd->client) {
1442  lives_printerr("jack_client_open() failed, status = 0x%2.0x\n", status);
1443  if (status & JackServerFailed) {
1444  d_print(_("Unable to connect to JACK server\n"));
1445  }
1446  return FALSE;
1447  }
1448 
1449  if (status & JackNameNotUnique) {
1450  client_name = jack_get_client_name(jackd->client);
1451  lives_printerr("unique name `%s' assigned\n", client_name);
1452  }
1453 
1454  jackd->sample_in_rate = jackd->sample_out_rate = jack_get_sample_rate(jackd->client);
1455 
1456  //lives_printerr (lives_strdup_printf("engine sample rate: %ld\n",jackd->sample_rate));
1457 
1458  // create ports for the client (left and right channels)
1459  for (i = 0; i < jackd->num_input_channels; i++) {
1460  char portname[32];
1461  lives_snprintf(portname, 32, "in_%d", i);
1462 
1463 #ifdef DEBUG_JACK_PORTS
1464  lives_printerr("input port %d is named '%s'\n", i, portname);
1465 #endif
1466  jackd->input_port[i] = jack_port_register(jackd->client, portname,
1467  JACK_DEFAULT_AUDIO_TYPE,
1468  JackPortIsInput | JackPortIsTerminal,
1469  0);
1470  if (!jackd->input_port[i]) {
1471  lives_printerr("ne more JACK input ports available\n");
1472  return FALSE;
1473  }
1474  }
1475 
1476  /* tell the JACK server to call `srate()' whenever
1477  the sample rate of the system changes. */
1478  jack_set_sample_rate_callback(jackd->client, jack_get_srate, jackd);
1479 
1480  /* tell the JACK server to call `jack_shutdown()' if
1481  it ever shuts down, either entirely, or if it
1482  just decides to stop calling us. */
1483  jack_on_shutdown(jackd->client, jack_shutdown, jackd);
1484 
1485  jrb = 0;
1486  // set process callback and start
1487  jack_set_process_callback(jackd->client, audio_read, jackd);
1488 
1489  return 0;
1490 }
1491 
1492 
1493 boolean jack_write_driver_activate(jack_driver_t *jackd) {
1494  // connect client and activate it
1495  int i;
1496  const char **ports;
1497  boolean failed = FALSE;
1498 
1499  if (jackd->is_active) return TRUE; // already running
1500 
1501  /* tell the JACK server that we are ready to roll */
1502  if (jack_activate(jackd->client)) {
1503  LIVES_ERROR("Cannot activate jack writer client");
1504  return FALSE;
1505  }
1506 
1507  // we are looking for input ports to connect to
1508  jackd->jack_port_flags |= JackPortIsInput;
1509 
1510  ports = jack_get_ports(jackd->client, NULL, NULL, jackd->jack_port_flags);
1511 
1512  if (!ports) {
1513  LIVES_ERROR("No jack input ports available !");
1514  return FALSE;
1515  }
1516 
1517  for (i = 0; ports[i]; i++) {
1518 #ifdef DEBUG_JACK_PORTS
1519  lives_printerr("ports[%d] = '%s'\n", i, ports[i]);
1520 #endif
1521  }
1522  jackd->in_chans_available = i;
1523 
1524  if (jackd->in_chans_available < jackd->num_output_channels) {
1525 #ifdef DEBUG_JACK_PORTS
1526  lives_printerr("ERR: jack_get_ports() failed to find enough ports with jack port flags of 0x%lX'\n", jackd->jack_port_flags);
1527 #endif
1528  free(ports);
1529  LIVES_ERROR("Not enough jack input ports available !");
1530  return FALSE;
1531  }
1532 
1533  /* connect the ports. Note: you can't do this before
1534  the client is activated (this may change in the future). */
1535  for (i = 0; i < jackd->num_output_channels; i++) {
1536 #ifdef DEBUG_JACK_PORTS
1537  lives_printerr("jack_connect() %s to port %d('%s')\n", jack_port_name(jackd->output_port[i]), i, ports[i]);
1538 #endif
1539  if (jack_connect(jackd->client, jack_port_name(jackd->output_port[i]), ports[i])) {
1540 #ifdef DEBUG_JACK_PORTS
1541  lives_printerr("cannot connect to output port %d('%s')\n", i, ports[i]);
1542 #endif
1543  LIVES_ERROR("Cannot connect all our jack outputs");
1544  failed = TRUE;
1545  }
1546  }
1547 
1548  free(ports);
1549 
1550  /* if something failed we need to shut the client down and return 0 */
1551  if (failed) {
1552  LIVES_ERROR("Jack writer creation failed, closing and returning error");
1553  jack_close_device(jackd);
1554  return FALSE;
1555  }
1556 
1557  // start using soundcard as timer source
1559 
1560  jackd->is_active = TRUE;
1561  jackd->jackd_died = FALSE;
1562  jackd->in_use = FALSE;
1563  jackd->is_paused = FALSE;
1564 
1565  d_print(_("Started jack audio subsystem.\n"));
1566 
1567  return TRUE;
1568 }
1569 
1570 
1571 boolean jack_read_driver_activate(jack_driver_t *jackd, boolean autocon) {
1572  // connect driver for reading
1573  const char **ports;
1574  boolean failed = FALSE;
1575  int i;
1576 
1577  if (!jackd->is_active) {
1578  if (jack_activate(jackd->client)) {
1579  LIVES_ERROR("Cannot activate jack reader client");
1580  return FALSE;
1581  }
1582  }
1583 
1584  if (!autocon && (prefs->jack_opts & JACK_OPTS_NO_READ_AUTOCON)) goto jackreadactive;
1585 
1586  // we are looking for output ports to connect to
1587  jackd->jack_port_flags |= JackPortIsOutput;
1588 
1589  ports = jack_get_ports(jackd->client, NULL, NULL, jackd->jack_port_flags);
1590 
1591  if (!ports) {
1592  LIVES_ERROR("No jack output ports available !");
1593  return FALSE;
1594  }
1595 
1596  for (i = 0; ports[i]; i++) {
1597 #ifdef DEBUG_JACK_PORTS
1598  lives_printerr("ports[%d] = '%s'\n", i, ports[i]);
1599 #endif
1600  }
1601  jackd->out_chans_available = i;
1602 
1603  if (jackd->out_chans_available < jackd->num_input_channels) {
1604 #ifdef DEBUG_JACK_PORTS
1605  lives_printerr("ERR: jack_get_ports() failed to find enough ports with jack port flags of 0x%lX'\n", jackd->jack_port_flags);
1606 #endif
1607  free(ports);
1608  LIVES_ERROR("Not enough jack output ports available !");
1609  return FALSE;
1610  }
1611 
1612  for (i = 0; i < jackd->num_input_channels; i++) {
1613 #ifdef DEBUG_JACK_PORTS
1614  lives_printerr("jack_connect() %s to port name %d('%s')\n", jack_port_name(jackd->input_port[i]), i, ports[i]);
1615 #endif
1616  if (jack_connect(jackd->client, ports[i], jack_port_name(jackd->input_port[i]))) {
1617 #ifdef DEBUG_JACK_PORTS
1618  lives_printerr("cannot connect to input port %d('%s')\n", i, ports[i]);
1619 #endif
1620  LIVES_ERROR("Cannot connect all our jack inputs");
1621  failed = TRUE;
1622  }
1623  }
1624 
1625  free(ports);
1626 
1627  if (failed) {
1628  lives_printerr("Failed, closing and returning error\n");
1629  jack_close_device(jackd);
1630  return FALSE;
1631  }
1632 
1633  // do we need to be connected for this ?
1634  // start using soundcard as timer source
1635  //prefs->force_system_clock = FALSE;
1636 
1637 jackreadactive:
1638 
1639  jackd->is_active = TRUE;
1640  jackd->jackd_died = FALSE;
1641  jackd->in_use = FALSE;
1642  jackd->is_paused = FALSE;
1643  jackd->nframes_start = 0;
1644  d_print(_("Started jack audio reader.\n"));
1645 
1646  // start using soundcard as timer source
1648 
1649  return TRUE;
1650 }
1651 
1652 
1653 jack_driver_t *jack_get_driver(int dev_idx, boolean is_output) {
1654  jack_driver_t *jackd;
1655 
1656  if (is_output) jackd = &outdev[dev_idx];
1657  else jackd = &indev[dev_idx];
1658 #ifdef TRACE_getReleaseDevice
1659  lives_printerr("dev_idx is %d\n", dev_idx);
1660 #endif
1661 
1662  return jackd;
1663 }
1664 
1665 
1666 int jack_audio_init(void) {
1667  // initialise variables
1668  int i, j;
1669  jack_driver_t *jackd;
1670 
1671  for (i = 0; i < JACK_MAX_OUTDEVICES; i++) {
1672  jackd = &outdev[i];
1673  //jack_reset_dev(i, TRUE);
1674  jackd->dev_idx = i;
1675  jackd->client = NULL;
1676  jackd->in_use = FALSE;
1677  for (j = 0; j < JACK_MAX_OUTPUT_PORTS; j++) jackd->volume[j] = 1.0f;
1678  jackd->state = (jack_transport_state_t)JackTClosed;
1679  jackd->sample_out_rate = jackd->sample_in_rate = 0;
1680  jackd->seek_pos = jackd->seek_end = jackd->real_seek_pos = 0;
1681  jackd->msgq = NULL;
1682  jackd->num_calls = 0;
1683  jackd->astream_fd = -1;
1684  jackd->abs_maxvol_heard = 0.;
1685  jackd->jackd_died = FALSE;
1686  jackd->num_output_channels = 2;
1687  jackd->play_when_stopped = FALSE;
1688  jackd->mute = FALSE;
1689  jackd->is_silent = FALSE;
1690  jackd->out_chans_available = 0;
1691  jackd->is_output = TRUE;
1692  jackd->read_abuf = -1;
1693  jackd->playing_file = -1;
1694  jackd->frames_written = 0;
1695  }
1696  return 0;
1697 }
1698 
1699 
1700 int jack_audio_read_init(void) {
1701  int i, j;
1702  jack_driver_t *jackd;
1703 
1704  for (i = 0; i < JACK_MAX_INDEVICES; i++) {
1705  jackd = &indev[i];
1706  //jack_reset_dev(i, FALSE);
1707  jackd->dev_idx = i;
1708  jackd->client = NULL;
1709  jackd->in_use = FALSE;
1710  for (j = 0; j < JACK_MAX_INPUT_PORTS; j++) jackd->volume[j] = 1.0f;
1711  jackd->state = (jack_transport_state_t)JackTClosed;
1712  jackd->sample_out_rate = jackd->sample_in_rate = 0;
1713  jackd->seek_pos = jackd->seek_end = jackd->real_seek_pos = 0;
1714  jackd->msgq = NULL;
1715  jackd->num_calls = 0;
1716  jackd->astream_fd = -1;
1717  jackd->abs_maxvol_heard = 0.;
1718  jackd->jackd_died = FALSE;
1719  jackd->num_input_channels = 2;
1720  jackd->play_when_stopped = FALSE;
1721  jackd->mute = FALSE;
1722  jackd->in_chans_available = 0;
1723  jackd->is_output = FALSE;
1724  jackd->playing_file = -1;
1725  jackd->frames_written = 0;
1726  }
1727  return 0;
1728 }
1729 
1730 
1731 volatile aserver_message_t *jack_get_msgq(jack_driver_t *jackd) {
1732  if (jackd->jackd_died || mainw->aplayer_broken) return NULL;
1733  return jackd->msgq;
1734 }
1735 
1736 
1737 void jack_time_reset(jack_driver_t *jackd, int64_t offset) {
1738  jackd->nframes_start = jack_frame_time(jack_transport_client) + (jack_nframes_t)((float)(offset / USEC_TO_TICKS) *
1739  (jack_get_sample_rate(jackd->client) / 1000000.));
1740  jackd->frames_written = 0;
1741  mainw->currticks = offset;
1742  mainw->deltaticks = mainw->startticks = 0;
1743 }
1744 
1745 
1746 ticks_t lives_jack_get_time(jack_driver_t *jackd) {
1747  // get the time in ticks since playback started
1748  volatile aserver_message_t *msg = jackd->msgq;
1749  jack_nframes_t frames, retframes;
1750  static jack_nframes_t last_frames = 0;
1751 
1752  if (!jackd->client) return -1;
1753 
1754  if (msg && msg->command == ASERVER_CMD_FILE_SEEK) {
1755  ticks_t timeout;
1757  while ((timeout = lives_alarm_check(alarm_handle)) > 0 && jack_get_msgq(jackd)) {
1758  sched_yield(); // wait for seek
1759  lives_usleep(prefs->sleep_time);
1760  }
1761  lives_alarm_clear(alarm_handle);
1762  if (timeout == 0) return -1;
1763  }
1764 
1765  frames = jack_frame_time(jackd->client);
1766 
1767  retframes = frames;
1768  if (last_frames > 0 && frames <= last_frames) {
1769  retframes += jackd->frames_written;
1770  } else jackd->frames_written = 0;
1771  last_frames = frames;
1772 
1773  return (ticks_t)((frames - jackd->nframes_start) * (1000000. / jack_get_sample_rate(
1774  jackd->client)) * USEC_TO_TICKS);
1775 }
1776 
1777 
1778 double lives_jack_get_pos(jack_driver_t *jackd) {
1779  // get current time position (seconds) in audio file
1780  if (jackd->playing_file > -1)
1781  return fwd_seek_pos / (double)(afile->arps * afile->achans * afile->asampsize / 8);
1782  // from memory
1783  return (double)jackd->frames_written / (double)jackd->sample_out_rate;
1784 
1785 }
1786 
1787 
1788 boolean jack_audio_seek_frame(jack_driver_t *jackd, double frame) {
1789  // seek to frame "frame" in current audio file
1790  // position will be adjusted to (floor) nearest sample
1791 
1792  volatile aserver_message_t *jmsg;
1793  int64_t seekstart;
1794  ticks_t timeout;
1795  double thresh = 0., delta = 0.;
1797 
1798  if (alarm_handle == ALL_USED) return FALSE;
1799 
1800  if (frame < 1) frame = 1;
1801 
1802  do {
1803  jmsg = jack_get_msgq(jackd);
1804  } while ((timeout = lives_alarm_check(alarm_handle)) > 0 && jmsg && jmsg->command != ASERVER_CMD_FILE_SEEK);
1805  lives_alarm_clear(alarm_handle);
1806  if (timeout == 0 || jackd->playing_file == -1) {
1807  return FALSE;
1808  }
1809  if (frame > afile->frames && afile->frames != 0) frame = afile->frames;
1810  seekstart = (int64_t)((double)(frame - 1.) / afile->fps * afile->arps) * afile->achans * (afile->asampsize / 8);
1811  if (cache_buffer) {
1812  delta = (double)(seekstart - lives_buffered_offset(cache_buffer->_fd)) / (double)(afile->arps * afile->achans *
1813  (afile->asampsize / 8));
1814  thresh = 1. / (double)afile->fps;
1815  }
1816  if (delta >= thresh || delta <= -thresh)
1817  jack_audio_seek_bytes(jackd, seekstart, afile);
1818  return TRUE;
1819 }
1820 
1821 
1822 int64_t jack_audio_seek_bytes(jack_driver_t *jackd, int64_t bytes, lives_clip_t *sfile) {
1823  // seek to position "bytes" in current audio file
1824  // position will be adjusted to (floor) nearest sample
1825 
1826  // if the position is > size of file, we will seek to the end of the file
1827 
1828  volatile aserver_message_t *jmsg;
1829  int64_t seekstart;
1830 
1831  ticks_t timeout;
1833 
1834  fwd_seek_pos = bytes;
1835 
1836  seek_err = FALSE;
1837 
1838  if (alarm_handle == -1) {
1839  LIVES_WARN("Invalid alarm handle");
1840  return 0;
1841  }
1842 
1843  if (jackd->in_use) {
1844  do {
1845  jmsg = jack_get_msgq(jackd);
1846  } while ((timeout = lives_alarm_check(alarm_handle)) > 0 && jmsg && jmsg->command != ASERVER_CMD_FILE_SEEK);
1847  lives_alarm_clear(alarm_handle);
1848  if (timeout == 0 || jackd->playing_file == -1) {
1849  if (timeout == 0) LIVES_WARN("Jack connect timed out");
1850  seek_err = TRUE;
1851  return 0;
1852  }
1853  }
1854 
1855  seekstart = ((int64_t)(bytes / sfile->achans / (sfile->asampsize / 8))) * sfile->achans * (sfile->asampsize / 8);
1856 
1857  if (seekstart < 0) seekstart = 0;
1858  if (seekstart > sfile->afilesize) seekstart = sfile->afilesize;
1859  jack_message2.command = ASERVER_CMD_FILE_SEEK;
1860  jack_message2.tc = lives_get_current_ticks();
1861  jack_message2.next = NULL;
1862  jack_message2.data = lives_strdup_printf("%"PRId64, seekstart);
1863  if (!jackd->msgq) jackd->msgq = &jack_message2;
1864  else jackd->msgq->next = &jack_message2;
1865  return seekstart;
1866 }
1867 
1868 
1869 boolean jack_try_reconnect(void) {
1870  jack_audio_init();
1871  jack_audio_read_init();
1872 
1873  // TODO: create the reader also
1874  mainw->jackd = jack_get_driver(0, TRUE);
1875  if (!jack_create_client_writer(mainw->jackd)) goto err123;
1876 
1877  d_print(_("\nConnection to jack audio was reset.\n"));
1878  return TRUE;
1879 
1880 err123:
1882  mainw->jackd = NULL;
1884  return FALSE;
1885 }
1886 
1887 
1888 void jack_pb_end(void) {
1889  cache_buffer = NULL;
1890 }
1891 
1892 
1893 void jack_aud_pb_ready(int fileno) {
1894  // TODO - can we merge with switch_audio_clip()
1895 
1896  // prepare to play file fileno
1897  // - set loop mode
1898  // - check if we need to reconnect
1899  // - set vals
1900 
1901  // called at pb start and rec stop (after rec_ext_audio)
1902  char *tmpfilename = NULL;
1903  lives_clip_t *sfile = mainw->files[fileno];
1904  int asigned = !(sfile->signed_endian & AFORM_UNSIGNED);
1905  int aendian = !(sfile->signed_endian & AFORM_BIG_ENDIAN);
1906 
1907  if (mainw->jackd && mainw->aud_rec_fd == -1) {
1908  mainw->jackd->is_paused = FALSE;
1909  mainw->jackd->mute = mainw->mute;
1912  mainw->jackd->loop = AUDIO_LOOP_PINGPONG;
1913  else mainw->jackd->loop = AUDIO_LOOP_FORWARD;
1914  } else mainw->jackd->loop = AUDIO_LOOP_NONE;
1915  if (sfile->achans > 0 && (!mainw->preview || (mainw->preview && mainw->is_processing)) &&
1916  (sfile->laudio_time > 0. || sfile->opening ||
1917  (mainw->multitrack && mainw->multitrack->is_rendering &&
1918  lives_file_test((tmpfilename = lives_get_audio_file_name(fileno)), LIVES_FILE_TEST_EXISTS)))) {
1919  ticks_t timeout;
1920  lives_alarm_t alarm_handle;
1921 
1922  lives_freep((void **)&tmpfilename);
1923  mainw->jackd->num_input_channels = sfile->achans;
1924  mainw->jackd->bytes_per_channel = sfile->asampsize / 8;
1925  mainw->jackd->sample_in_rate = sfile->arate;
1926  mainw->jackd->usigned = !asigned;
1927  mainw->jackd->seek_end = sfile->afilesize;
1928 
1929  if ((aendian && (capable->byte_order == LIVES_BIG_ENDIAN)) || (!aendian && (capable->byte_order == LIVES_LITTLE_ENDIAN)))
1930  mainw->jackd->reverse_endian = TRUE;
1931  else mainw->jackd->reverse_endian = FALSE;
1932 
1933  alarm_handle = lives_alarm_set(LIVES_DEFAULT_TIMEOUT);
1934  while ((timeout = lives_alarm_check(alarm_handle)) > 0 && jack_get_msgq(mainw->jackd)) {
1935  sched_yield(); // wait for seek
1936  lives_usleep(prefs->sleep_time);
1937  }
1938  lives_alarm_clear(alarm_handle);
1939  if (timeout == 0) jack_try_reconnect();
1940 
1941  if ((!mainw->multitrack || mainw->multitrack->is_rendering) &&
1943  // tell jack server to open audio file and start playing it
1944  jack_message.command = ASERVER_CMD_FILE_OPEN;
1945  jack_message.data = lives_strdup_printf("%d", fileno);
1946 
1947  jack_message.next = NULL;
1948  mainw->jackd->msgq = &jack_message;
1949 
1950  jack_audio_seek_bytes(mainw->jackd, sfile->aseek_pos, sfile);
1951  if (seek_err) {
1952  if (jack_try_reconnect()) jack_audio_seek_bytes(mainw->jackd, sfile->aseek_pos, sfile);
1953  }
1954 
1955  //mainw->jackd->in_use = TRUE;
1956  mainw->rec_aclip = fileno;
1957  mainw->rec_avel = sfile->arate / sfile->arps;
1958  mainw->rec_aseek = (double)sfile->aseek_pos / (double)(sfile->arps * sfile->achans * (sfile->asampsize / 8));
1959  }
1960  }
1961  if ((mainw->agen_key != 0 || mainw->agen_needs_reinit)
1962  && !mainw->multitrack && !mainw->preview) mainw->jackd->in_use = TRUE; // audio generator is active
1963  }
1964 }
1965 
1966 #undef afile
1967 
1968 #endif
lives_freep
boolean lives_freep(void **ptr)
Definition: utils.c:1411
mainwindow::jackd
void * jackd
jack audio player / transport
Definition: mainwindow.h:1453
AFORM_UNSIGNED
#define AFORM_UNSIGNED
Definition: main.h:786
lives_setenv
boolean lives_setenv(const char *name, const char *value)
Definition: utils.c:120
lives_adjustment_set_value
WIDGET_HELPER_GLOBAL_INLINE boolean lives_adjustment_set_value(LiVESAdjustment *adj, double value)
Definition: widget-helper.c:5636
JACK_OPTS_TIMEBASE_LSTART
#define JACK_OPTS_TIMEBASE_LSTART
LiVES sets play start position.
Definition: preferences.h:242
mainwindow::startticks
volatile ticks_t startticks
effective ticks when current frame was (should have been) displayed
Definition: mainwindow.h:997
LIVES_IS_PLAYING
#define LIVES_IS_PLAYING
Definition: main.h:840
get_audio_from_plugin
boolean get_audio_from_plugin(float **fbuffer, int nchans, int arate, int nsamps, boolean is_audio_thread)
Definition: audio.c:3332
LIVES_LOCAL_INLINE
#define LIVES_LOCAL_INLINE
Definition: main.h:246
lives_get_current_playback_ticks
ticks_t lives_get_current_playback_ticks(ticks_t origsecs, ticks_t origusecs, lives_time_source_t *time_source)
Definition: utils.c:1481
add_to_ascrap_mb
void add_to_ascrap_mb(uint64_t bytes)
Definition: saveplay.c:5225
lives_audio_buf_t::operation
lives_operation_t operation
Definition: audio.h:77
mainwindow::effects_paused
boolean effects_paused
Definition: mainwindow.h:1055
lives_audio_buf_t::out_achans
int out_achans
channels for buffer* side
Definition: audio.h:96
ASERVER_CMD_FILE_SEEK
#define ASERVER_CMD_FILE_SEEK
Definition: audio.h:59
PRId64
#define PRId64
Definition: machinestate.h:169
lives_audio_buf_t::swap_sign
int swap_sign
Definition: audio.h:99
lives_free
#define lives_free
Definition: machinestate.h:52
lives_clip_t::aseek_pos
volatile off64_t aseek_pos
audio seek posn. (bytes) for when we switch clips
Definition: main.h:1064
LIVES_WARN
#define LIVES_WARN(x)
Definition: main.h:1862
mainwindow::rec_samples
int64_t rec_samples
Definition: mainwindow.h:1527
lives_malloc
#define lives_malloc
Definition: machinestate.h:46
mainwindow::is_ready
boolean is_ready
Definition: mainwindow.h:787
lives_audio_buf_t::eof
boolean eof
did we read EOF ? [readonly by client]
Definition: audio.h:79
has_audio_filters
boolean has_audio_filters(lives_af_t af_type)
Definition: effects-weed.c:3859
do_jack_lost_conn_error
LIVES_GLOBAL_INLINE void do_jack_lost_conn_error(void)
Definition: dialogs.c:4512
mainwindow::record
volatile boolean record
Definition: mainwindow.h:794
_vid_playback_plugin::render_audio_frame_float
boolean(* render_audio_frame_float)(float **audio, int nsamps)
Definition: plugins.h:175
lives_unsetenv
boolean lives_unsetenv(const char *name)
Definition: utils.c:132
lives_get_audio_file_name
LIVES_GLOBAL_INLINE char * lives_get_audio_file_name(int fnum)
Definition: audio.c:55
lives_audio_buf_t
Definition: audio.h:76
check_for_disk_space
boolean check_for_disk_space(boolean fullcheck)
Definition: saveplay.c:5416
USEC_TO_TICKS
#define USEC_TO_TICKS
multiplying factor uSec -> ticks_t (def. 100)
Definition: mainwindow.h:38
weed_layer_new
LIVES_GLOBAL_INLINE weed_layer_t * weed_layer_new(int layer_type)
Definition: colourspace.c:9655
_prefs::jack_aserver
char jack_aserver[PATH_MAX]
Definition: preferences.h:245
SWAP_X_TO_L
#define SWAP_X_TO_L
endian swapping
Definition: audio.h:19
_prefs::jack_opts
uint32_t jack_opts
Definition: preferences.h:232
mainwindow::current_file
int current_file
Definition: mainwindow.h:727
IS_VALID_CLIP
#define IS_VALID_CLIP(clip)
Definition: main.h:808
mainwindow::vpp
_vid_playback_plugin * vpp
video plugin
Definition: mainwindow.h:1572
lives_audio_buf_t::samples_filled
volatile size_t samples_filled
number of samples filled (readonly client)
Definition: audio.h:124
lives_toggle_tool_button_set_active
WIDGET_HELPER_GLOBAL_INLINE boolean lives_toggle_tool_button_set_active(LiVESToggleToolButton *button, boolean active)
Definition: widget-helper.c:4525
lives_realloc
#define lives_realloc
Definition: machinestate.h:49
cfile
#define cfile
Definition: main.h:1833
mainwindow::preview
boolean preview
Definition: mainwindow.h:757
lives_chmod
int lives_chmod(const char *target, const char *mode)
Definition: utils.c:4475
effects.h
ASERVER_CMD_FILE_CLOSE
#define ASERVER_CMD_FILE_CLOSE
Definition: audio.h:58
LIVES_READ_OPERATION
@ LIVES_READ_OPERATION
Definition: audio.h:71
LIVES_ERROR
#define LIVES_ERROR(x)
Definition: main.h:1870
prefs
_prefs * prefs
Definition: preferences.h:847
audio_stream
LIVES_GLOBAL_INLINE void audio_stream(void *buff, size_t nbytes, int fd)
Definition: audio.c:3964
mainwindow::video_seek_ready
volatile boolean video_seek_ready
Definition: mainwindow.h:939
JACK_OPTS_TRANSPORT_CLIENT
#define JACK_OPTS_TRANSPORT_CLIENT
jack can start/stop
Definition: preferences.h:233
EXEC_JACKD
#define EXEC_JACKD
recommended if (!have_pulseaudio)
Definition: mainwindow.h:417
mainwindow::loop_video
LiVESWidget * loop_video
Definition: mainwindow.h:1173
lives_alarm_clear
boolean lives_alarm_clear(lives_alarm_t alarm_handle)
Definition: utils.c:1732
TICKS_PER_SECOND_DBL
#define TICKS_PER_SECOND_DBL
actually microseconds / 100.
Definition: mainwindow.h:37
mainwindow::ext_audio_mon
LiVESWidget * ext_audio_mon
Definition: mainwindow.h:1359
capability::mainpid
pid_t mainpid
Definition: main.h:591
mainwindow::agen_needs_reinit
volatile boolean agen_needs_reinit
Definition: mainwindow.h:1650
ABS
#define ABS(a)
Definition: videoplugin.h:63
LIVES_DEFAULT_TIMEOUT
#define LIVES_DEFAULT_TIMEOUT
Definition: mainwindow.h:43
fastrand
LIVES_GLOBAL_INLINE uint64_t fastrand(void)
Definition: machinestate.c:40
ALIGN_CEIL64
#define ALIGN_CEIL64(a, b)
Definition: main.h:289
AUDIO_LOOP_NONE
@ AUDIO_LOOP_NONE
Definition: audio.h:146
mainwindow::cache_buffer_mutex
pthread_mutex_t cache_buffer_mutex
sync for jack playback termination
Definition: mainwindow.h:1502
WEED_LEAF_HOST_KEEP_ADATA
#define WEED_LEAF_HOST_KEEP_ADATA
Definition: audio.h:51
lives_ruler_set_value
WIDGET_HELPER_GLOBAL_INLINE double lives_ruler_set_value(LiVESRuler *ruler, double value)
Definition: widget-helper.c:5284
lives_alarm_t
int lives_alarm_t
Definition: mainwindow.h:696
mainwindow::event_list
weed_event_t * event_list
current event_list, for recording
Definition: mainwindow.h:803
ticks_t
int64_t ticks_t
Definition: main.h:97
mainwindow::rec_aclip
volatile int rec_aclip
recording values - to be inserted at the following video frame
Definition: mainwindow.h:967
JACK_OPTS_TIMEBASE_CLIENT
#define JACK_OPTS_TIMEBASE_CLIENT
full timebase client
Definition: preferences.h:239
lives_audio_buf_t::out_asamps
int out_asamps
Definition: audio.h:98
TRUE
#define TRUE
Definition: videoplugin.h:59
lives_memset
#define lives_memset
Definition: machinestate.h:61
mainwindow::whentostop
volatile lives_whentostop_t whentostop
Definition: mainwindow.h:929
weed_apply_audio_effects_rt
void weed_apply_audio_effects_rt(weed_layer_t *alayer, weed_timecode_t tc, boolean analysers_only, boolean is_audio_thread)
Definition: effects-weed.c:3743
THREADVAR
#define THREADVAR(var)
Definition: machinestate.h:531
mainwindow::loop_cont
volatile boolean loop_cont
Definition: mainwindow.h:764
mainwindow::cancelled
volatile lives_cancel_t cancelled
Definition: mainwindow.h:798
AUD_WRITE_CHECK
#define AUD_WRITE_CHECK
after recording this many bytes we check disk space (default 128MB)
Definition: audio.h:49
lives_audio_buf_t::seek
off_t seek
Definition: audio.h:85
_prefs::audio_opts
volatile uint32_t audio_opts
Definition: preferences.h:254
lives_audio_buf_t::die
volatile boolean die
set to TRUE to shut down thread
Definition: audio.h:140
sample_move_d16_float
float sample_move_d16_float(float *dst, short *src, uint64_t nsamples, uint64_t src_skip, int is_unsigned, boolean rev_endian, float vol)
Definition: audio.c:677
callbacks.h
lives_clip_t::cb_src
int cb_src
source clip for clipboard; for other clips, may be used to hold some temporary linkage
Definition: main.h:1086
_prefs::audio_src
int audio_src
Definition: preferences.h:204
mainwindow::fps_mini_measure
frames_t fps_mini_measure
show fps stats during playback
Definition: mainwindow.h:779
capable
capability * capable
Definition: main.h:627
mainwindow::crash_possible
int crash_possible
Definition: mainwindow.h:1722
d_print
void d_print(const char *fmt,...)
Definition: utils.c:2542
mainwindow::rec_aseek
volatile double rec_aseek
Definition: mainwindow.h:969
mainwindow::avseek_mutex
pthread_mutex_t avseek_mutex
Definition: mainwindow.h:938
ALL_USED
#define ALL_USED
Definition: mainwindow.h:192
sample_move_abuf_float
int64_t sample_move_abuf_float(float **obuf, int nchans, int nsamps, int out_arate, float vol)
copy audio data from cache into audio sound buffer
Definition: audio.c:888
mainwindow::deltaticks
ticks_t deltaticks
deltaticks for scratching
Definition: mainwindow.h:1006
lives_clip_t::signed_endian
uint32_t signed_endian
bitfield
Definition: main.h:909
lives_audio_buf_t::in_interleaf
boolean in_interleaf
Definition: audio.h:92
SignalHandlerPointer
void(* SignalHandlerPointer)(int)
Definition: main.h:1464
mainwindow::origsecs
ticks_t origsecs
playback start seconds - subtracted from all other ticks to keep numbers smaller
Definition: mainwindow.h:1000
mainwindow::playing_sel
boolean playing_sel
list of set names in current workdir, mau be NULL
Definition: mainwindow.h:756
lives_audio_buf_t::bytesize
ssize_t bytesize
Definition: audio.h:90
mainwindow::signals_deferred
boolean signals_deferred
Definition: mainwindow.h:1674
mt_tl_move
void mt_tl_move(lives_mt *mt, double pos)
Definition: multitrack.c:3595
lives_audio_buf_t::fileno
int fileno
Definition: audio.h:80
STOP_ON_AUD_END
@ STOP_ON_AUD_END
Definition: main.h:695
lives_clip_t::afilesize
size_t afilesize
Definition: main.h:912
lives_audio_buf_t::bufferf
float ** bufferf
sample data in float format (or NULL)
Definition: audio.h:115
mainwindow::playing_file
int playing_file
which number file we are playing (or -1) [generally mainw->current_file]
Definition: mainwindow.h:943
get_location
void get_location(const char *exe, char *val, int maxlen)
Definition: utils.c:3407
ASERVER_CMD_PROCESSED
#define ASERVER_CMD_PROCESSED
asynch msging
Definition: audio.h:56
lives_buffered_offset
off_t lives_buffered_offset(int fd)
Definition: utils.c:1364
mainwindow::files
lives_clip_t * files[MAX_FILES+1]
+1 for the clipboard
Definition: mainwindow.h:729
_future_prefs::volume
volatile float volume
audio volume level (for jack and pulse)
Definition: preferences.h:837
mainwindow::audio_seek_ready
volatile boolean audio_seek_ready
Definition: mainwindow.h:940
CANCEL_NONE
@ CANCEL_NONE
no cancel
Definition: main.h:701
audio_cache_get_buffer
LIVES_GLOBAL_INLINE lives_audio_buf_t * audio_cache_get_buffer(void)
Definition: audio.c:3324
weed_layer_set_audio_data
LIVES_GLOBAL_INLINE weed_layer_t * weed_layer_set_audio_data(weed_layer_t *layer, float **data, int arate, int naudchans, weed_size_t nsamps)
Definition: colourspace.c:9681
lives_get_current_ticks
LIVES_GLOBAL_INLINE ticks_t lives_get_current_ticks(void)
Definition: machinestate.c:835
JACK_OPTS_NO_READ_AUTOCON
#define JACK_OPTS_NO_READ_AUTOCON
do not auto con. rd clients when playing ext aud
Definition: preferences.h:241
lives_clip_t::arps
int arps
audio physical sample rate (i.e the "normal" sample rate of the clip when played at 1,...
Definition: main.h:905
lives_audio_buf_t::samp_space
size_t samp_space
buffer space in samples (* by sizeof(type) to get bytesize) [if interleaf, also * by chans]
Definition: audio.h:103
catch_sigint
void catch_sigint(int signum)
Definition: main.c:296
lives_strdup_printf
#define lives_strdup_printf(fmt,...)
Definition: support.c:27
mainwindow::ext_audio
volatile boolean ext_audio
using external video playback plugin to stream audio
Definition: mainwindow.h:774
lives_clip_t::opening
boolean opening
Definition: main.h:946
mainwindow::audio_filewriteend_mutex
pthread_mutex_t audio_filewriteend_mutex
sync for ending writing audio to file
Definition: mainwindow.h:1503
weed_layer_t
weed_plant_t weed_layer_t
Definition: colourspace.h:71
mainwindow::scratch
volatile short scratch
Definition: mainwindow.h:1026
append_to_audio_bufferf
void append_to_audio_bufferf(float *src, uint64_t nsamples, int channum)
Definition: audio.c:82
mainwindow::ascrap_file
int ascrap_file
scrap file for recording audio scraps
Definition: mainwindow.h:875
AUDIO_OPTS_FOLLOW_FPS
#define AUDIO_OPTS_FOLLOW_FPS
Definition: preferences.h:256
mainwindow::uflow_count
volatile int uflow_count
experimental values, primarily for testing
Definition: mainwindow.h:1761
wake_audio_thread
void wake_audio_thread(void)
Definition: audio.c:3230
sample_silence_stream
void sample_silence_stream(int nchans, int64_t nframes)
Definition: audio.c:421
mainwindow::faded
boolean faded
Definition: mainwindow.h:759
aserver_message_t::data
volatile char * data
Definition: audio.h:65
lives_memcpy
#define lives_memcpy
Definition: machinestate.h:55
mainwindow::rec_avel
volatile double rec_avel
Definition: mainwindow.h:968
future_prefs
_future_prefs * future_prefs
Definition: preferences.h:848
mainwindow::multitrack
lives_mt * multitrack
holds a pointer to the entire multitrack environment; NULL in Clip Edit mode
Definition: mainwindow.h:1087
lives_audio_buf_t::shrink_factor
double shrink_factor
resampling ratio
Definition: audio.h:101
ASERVER_CMD_FILE_OPEN
#define ASERVER_CMD_FILE_OPEN
Definition: audio.h:57
lives_alarm_check
ticks_t lives_alarm_check(lives_alarm_t alarm_handle)
Definition: utils.c:1687
lives_vol_from_linear
#define lives_vol_from_linear(vol)
Definition: audio.h:269
LIVES_SHORT_TIMEOUT
#define LIVES_SHORT_TIMEOUT
Definition: mainwindow.h:42
mainwindow::go_away
boolean go_away
Definition: mainwindow.h:1614
lives_clip_t::laudio_time
double laudio_time
Definition: main.h:929
mainwindow::aud_rec_fd
int aud_rec_fd
fd of file we are recording audio to
Definition: mainwindow.h:1525
mainwindow::record_paused
volatile boolean record_paused
pause during recording
Definition: mainwindow.h:1557
sample_silence_dS
LIVES_GLOBAL_INLINE void sample_silence_dS(float *dst, uint64_t nsamples)
Definition: audio.c:415
on_playall_activate
void on_playall_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:4530
filename_from_fd
char * filename_from_fd(char *val, int fd)
: return filename from an open fd, freeing val first
Definition: utils.c:60
AF_TYPE_ANY
@ AF_TYPE_ANY
Definition: effects.h:41
main.h
WEED_LAYER_TYPE_AUDIO
#define WEED_LAYER_TYPE_AUDIO
Definition: colourspace.h:222
mainwindow::play_end
frames_t play_end
Definition: mainwindow.h:931
mainwindow::fs
boolean fs
Definition: mainwindow.h:762
_prefs::sleep_time
int sleep_time
Definition: preferences.h:176
JACK_OPTS_TRANSPORT_MASTER
#define JACK_OPTS_TRANSPORT_MASTER
transport master
Definition: preferences.h:234
AUDIO_SRC_EXT
#define AUDIO_SRC_EXT
Definition: preferences.h:206
set_signal_handlers
void set_signal_handlers(SignalHandlerPointer sigfunc)
Definition: main.c:4077
aserver_message_t
Definition: audio.h:62
mainw
mainwindow * mainw
Definition: main.c:103
mainwindow::jack_can_stop
boolean jack_can_stop
Definition: mainwindow.h:934
AUDIO_LOOP_FORWARD
@ AUDIO_LOOP_FORWARD
Definition: audio.h:147
mainwindow::audio_frame_buffer
volatile lives_audio_buf_t * audio_frame_buffer
used for buffering / feeding audio to video generators
Definition: mainwindow.h:1697
_prefs::force_system_clock
boolean force_system_clock
Definition: preferences.h:366
CANCEL_KEEP
@ CANCEL_KEEP
user pressed 'Keep'
Definition: main.h:734
lives_audio_buf_t::is_ready
volatile boolean is_ready
Definition: audio.h:78
lives_system
int lives_system(const char *com, boolean allow_error)
Definition: utils.c:145
weed_layer_get_audio_data
LIVES_GLOBAL_INLINE float ** weed_layer_get_audio_data(weed_layer_t *layer, int *naudchans)
Definition: colourspace.c:13921
mainwindow::hruler
LiVESWidget * hruler
Definition: mainwindow.h:1230
weed_layer_free
LIVES_GLOBAL_INLINE weed_layer_t * weed_layer_free(weed_layer_t *layer)
frees pixel_data for a layer, then the layer itself
Definition: colourspace.c:13883
lives_audio_buf_t::out_interleaf
boolean out_interleaf
Definition: audio.h:93
lives_audio_buf_t::swap_endian
int swap_endian
Definition: audio.h:100
PATH_MAX
#define PATH_MAX
Definition: main.h:255
mainwindow::fps_mini_ticks
ticks_t fps_mini_ticks
Definition: mainwindow.h:780
mainwindow::aud_data_written
uint64_t aud_data_written
Definition: mainwindow.h:1720
lives_clip_t
corresponds to one clip in the GUI
Definition: main.h:877
defer_sigint
void defer_sigint(int signum)
Definition: main.c:282
mainwindow::is_processing
boolean is_processing
states
Definition: mainwindow.h:820
lives_audio_buf_t::sequential
boolean sequential
hint that we will read sequentially starting from seek
Definition: audio.h:105
lives_audio_buf_t::_fd
int _fd
file descriptor
Definition: audio.h:131
effects-weed.h
mainwindow::mute
boolean mute
Definition: mainwindow.h:770
lives_widget_queue_draw_if_visible
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_queue_draw_if_visible(LiVESWidget *widget)
Definition: widget-helper.c:11009
lives_audio_buf_t::in_asamps
int in_asamps
Definition: audio.h:97
aserver_message_t::next
volatile struct _aserver_message_t * next
Definition: audio.h:66
CANCEL_AUD_END
@ CANCEL_AUD_END
video playback completed
Definition: main.h:737
mainwindow::currticks
volatile ticks_t currticks
wall clock time, updated whenever lives_get_*_ticks is called
Definition: mainwindow.h:1005
mainwindow::ping_pong
volatile boolean ping_pong
Definition: mainwindow.h:765
AUDIO_OPTS_FOLLOW_CLIPS
#define AUDIO_OPTS_FOLLOW_CLIPS
Definition: preferences.h:255
lives_clip_t::asampsize
int asampsize
audio sample size in bits (8 or 16)
Definition: main.h:908
mainwindow::agen_key
volatile int agen_key
which fx key is generating audio [1 based] (or 0 for none)
Definition: mainwindow.h:1649
mainwindow::vpp_stream_mutex
pthread_mutex_t vpp_stream_mutex
prevent from writing audio when stream is closing
Definition: mainwindow.h:1501
SCRATCH_JUMP
#define SCRATCH_JUMP
jump and resync audio
Definition: mainwindow.h:1031
sample_move_float_int
int64_t sample_move_float_int(void *holding_buff, float **float_buffer, int nsamps, double scale, int chans, int asamps, int usigned, boolean rev_endian, boolean interleaved, float vol)
convert float samples back to int interleaved is for the float buffer; output int is always interleav...
Definition: audio.c:793
lives_clip_t::arate
int arate
current audio playback rate (varies if the clip rate is changed)
Definition: main.h:906
FALSE
#define FALSE
Definition: videoplugin.h:60
on_stop_activate
void on_stop_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:4748
clip_can_reverse
boolean clip_can_reverse(int clipno)
Definition: callbacks.c:4980
lives_alarm_set
lives_alarm_t lives_alarm_set(ticks_t ticks)
set alarm for now + delta ticks (10 nanosec) param ticks (10 nanoseconds) is the offset when we want ...
Definition: utils.c:1643
_
#define _(String)
Definition: support.h:44
aserver_message_t::command
volatile int command
Definition: audio.h:63
AUDIO_LOOP_PINGPONG
@ AUDIO_LOOP_PINGPONG
Definition: audio.h:148
capability::byte_order
int byte_order
Definition: main.h:577
JACK_OPTS_START_TSERVER
#define JACK_OPTS_START_TSERVER
start transport server
Definition: preferences.h:235
LIVES_INLINE
#define LIVES_INLINE
Definition: main.h:238
JACK_OPTS_START_ASERVER
#define JACK_OPTS_START_ASERVER
start audio server
Definition: preferences.h:237
mainwindow::orignsecs
ticks_t orignsecs
usecs at start of playback - ditto
Definition: mainwindow.h:1001
lives_clip_t::achans
int achans
number of audio channels (0, 1 or 2)
Definition: main.h:907
lives_audio_buf_t::buffer16
short ** buffer16
sample data in 16 bit format (or NULL)
Definition: audio.h:110
AFORM_BIG_ENDIAN
#define AFORM_BIG_ENDIAN
Definition: main.h:787
mainwindow::aplayer_broken
boolean aplayer_broken
Definition: mainwindow.h:1653
AF_TYPE_A
@ AF_TYPE_A
Definition: effects.h:42
lives_audio_buf_t::in_achans
int in_achans
channels for _filebuffer side
Definition: audio.h:95
mainwindow::avseek_cond
pthread_cond_t avseek_cond
Definition: mainwindow.h:937
mainwindow::jack_can_start
boolean jack_can_start
Definition: mainwindow.h:934