8#include <jack/jslist.h>
9#include <jack/control.h>
17#define afile mainw->files[jackd->playing_file]
19static jack_client_t *jack_transport_client;
22static unsigned char *zero_buff = NULL;
23static size_t zero_buff_count = 0;
25static boolean seek_err;
28static jackctl_server_t *jackserver = NULL;
31#define JACK_READ_BYTES 262144
33static uint8_t jrbuf[JACK_READ_BYTES * 2];
37static off_t fwd_seek_pos = 0;
39static 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);
43#ifdef ENABLE_JACK_TRANSPORT
44static boolean jack_playall(livespointer data) {
52 return (int64_t)((double)(val + mod - 1.) / (double)mod) * (int64_t)mod;
55static 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);
59 lives_memset(zero_buff + zero_buff_count, 0, check_size - zero_buff_count);
60 zero_buff_count = check_size;
71boolean lives_jack_init(
void) {
73 jack_options_t options = JackServerName;
76 jackctl_driver_t *driver = NULL;
79 const char *server_name = JACK_DEFAULT_SERVER_NAME;
81 jack_transport_client = NULL;
85 const JSList *drivers;
90 jackserver = jackctl_server_create(NULL, NULL);
98 params = jackctl_server_get_parameters(jackserver);
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;
104 jackctl_parameter_set_value(parameter, &value);
107 params = jack_slist_next(params);
111 drivers = jackctl_server_get_drivers_list(jackserver);
113 driver = (jackctl_driver_t *)drivers->data;
114 if (!strcmp(jackctl_driver_get_name(driver), JACK_DRIVER_NAME)) {
117 drivers = jack_slist_next(drivers);
120 LIVES_ERROR(
"Could not find a suitable driver for jack");
124 if (!jackctl_server_open(jackserver, driver)) {
125 LIVES_ERROR(
"Could not create the driver for jack");
129 if (!jackctl_server_start(jackserver)) {
137 options = (jack_options_t)((
int)options | (int)JackNoStartServer);
150 if (strlen(jackd_loc)) {
160 options = (jack_options_t)((
int)options | (int)JackNoStartServer);
166 jack_transport_client = jack_client_open(jt_client, options, &status, server_name);
169 if (!jack_transport_client)
return FALSE;
171#ifdef ENABLE_JACK_TRANSPORT
172 jack_activate(jack_transport_client);
173 jack_set_sync_timeout(jack_transport_client, 5000000);
174 jack_set_sync_callback(jack_transport_client, lives_start_ready_callback, NULL);
177 jack_client_close(jack_transport_client);
178 jack_transport_client = NULL;
181 if (status & JackServerStarted) {
182 d_print(
_(
"JACK server started\n"));
192ticks_t jack_transport_get_current_ticks(
void) {
193#ifdef ENABLE_JACK_TRANSPORT
195 jack_nframes_t srate;
198 jack_transport_query(jack_transport_client, &pos);
200 srate = jack_get_sample_rate(jack_transport_client);
201 val = (double)pos.frame / (
double)srate;
209#ifdef ENABLE_JACK_TRANSPORT
210static void jack_transport_check_state(
void) {
212 jack_transport_state_t jacktstate;
219 if (!jack_transport_client)
return;
221 jacktstate = jack_transport_query(jack_transport_client, &pos);
223 if (
mainw->
jack_can_start && (jacktstate == JackTransportRolling || jacktstate == JackTransportStarting) &&
227 lives_timer_add_simple(0, jack_playall, NULL);
231 if (jacktstate == JackTransportStopped) {
241boolean lives_jack_poll(
void) {
244#ifdef ENABLE_JACK_TRANSPORT
245 jack_transport_check_state();
251void lives_jack_end(
void) {
252#ifdef ENABLE_JACK_TRANSPORT
253 jack_client_t *client = jack_transport_client;
255 jack_transport_client = NULL;
256#ifdef ENABLE_JACK_TRANSPORT
258 jack_deactivate(client);
259 jack_client_close(client);
263 if (jackserver) jackctl_server_destroy(jackserver);
269void jack_pb_start(
double pbtime) {
271#ifdef ENABLE_JACK_TRANSPORT
274 jack_transport_locate(jack_transport_client, pbtime * jack_get_sample_rate(jack_transport_client));
275 jack_transport_start(jack_transport_client);
281void jack_pb_stop(
void) {
283#ifdef ENABLE_JACK_TRANSPORT
291static jack_driver_t outdev[JACK_MAX_OUTDEVICES];
292static jack_driver_t indev[JACK_MAX_INDEVICES];
314void jack_get_rec_avals(jack_driver_t *jackd) {
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;
324static void jack_set_rec_avals(jack_driver_t *jackd) {
328 jack_get_rec_avals(jackd);
333size_t jack_get_buffsize(jack_driver_t *jackd) {
334 if (cache_buffer)
return cache_buffer->
bytesize;
339static 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) {
343 if (!cache_buffer)
return;
345 qnt = afile->achans * (afile->asampsize >> 3);
346 jackd->seek_pos = align_ceilng(jackd->seek_pos, qnt);
351 cache_buffer->
fileno = jackd->playing_file;
353 cache_buffer->
seek = jackd->seek_pos;
356 cache_buffer->
in_achans = jackd->num_input_channels;
357 cache_buffer->
out_achans = jackd->num_output_channels;
359 cache_buffer->
in_asamps = afile->asampsize;
364 cache_buffer->
swap_sign = jackd->usigned;
384static void output_silence(
size_t offset, nframes_t nframes, jack_driver_t *jackd,
float **out_buffer) {
386 for (
int i = 0; i < jackd->num_output_channels; i++) {
387 if (!jackd->is_silent) {
400 if (jackd->astream_fd != -1) {
402 size_t rbytes = nframes * jackd->num_output_channels * 2;
403 check_zero_buff(rbytes);
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;
413static int audio_process(nframes_t nframes,
void *arg) {
415 float *out_buffer[JACK_MAX_OUTPUT_PORTS];
416 jack_driver_t *jackd = (jack_driver_t *)arg;
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;
430 lives_printerr(
"nframes %ld, sizeof(float) == %d\n", (int64_t)nframes,
sizeof(
float));
440 new_file = atoi((
char *)msg->
data);
441 if (jackd->playing_file != new_file) {
442 jackd->playing_file = new_file;
444 jackd->seek_pos = jackd->real_seek_pos = 0;
447 jackd->playing_file = -1;
448 jackd->in_use =
FALSE;
449 jackd->seek_pos = jackd->real_seek_pos = fwd_seek_pos = 0;
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;
467 jackd->msgq = msg->
next;
468 if (jackd->msgq && jackd->msgq->next == jackd->msgq) jackd->msgq->next = NULL;
472 for (i = 0; i < jackd->num_output_channels; i++)
473 out_buffer[i] = (
float *)jack_port_get_buffer(jackd->output_port[i], nframes);
476 output_silence(0, nframes, jackd, out_buffer);
480 fwd_seek_pos = jackd->real_seek_pos = jackd->seek_pos;
487 && jackd->in_use && jackd->playing_file > -1) {
490 if (jackd->read_abuf == -1) {
494 if (!jackd->is_silent) {
495 output_silence(0, nframes, jackd, out_buffer);
496 jackd->is_silent =
TRUE;
500 if (cache_buffer->
fileno == -1) jackd->playing_file = -1;
502 if (cache_buffer && cache_buffer->
in_achans > 0 && !cache_buffer->
is_ready) wait_cache_buffer =
TRUE;
505 jackd->state = jack_transport_query(jackd->client, &pos);
508 lives_printerr(
"STATE is %d %d\n", jackd->state, jackd->play_when_stopped);
512 if (jackd->state == JackTransportRolling || jackd->play_when_stopped) {
513 uint64_t jackFramesAvailable = nframes;
514 uint64_t inputFramesAvailable;
515 uint64_t numFramesToWrite;
516 int64_t in_frames = 0;
517 uint64_t in_bytes = 0, xin_bytes = 0;
518 float shrink_factor = 1.f;
525 lives_printerr(
"playing... jackFramesAvailable = %ld\n", jackFramesAvailable);
530 if (!jackd->in_use || ((jackd->playing_file < 0 || jackd->seek_pos < 0.) && jackd->read_abuf < 0
533 || jackd->is_paused) {
535 if (!jackd->is_silent) {
536 output_silence(0, nframes, jackd, out_buffer);
537 jackd->is_silent =
TRUE;
542 jackd->is_silent =
FALSE;
546 if (!jackd->is_silent) {
547 output_silence(0, nframes, jackd, out_buffer);
548 jackd->is_silent =
TRUE;
550 fwd_seek_pos = jackd->real_seek_pos = jackd->seek_pos;
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;
559 if (cache_buffer) push_cache_buffer(cache_buffer, jackd, in_bytes, nframes, shrink_factor);
570 if (LIVES_LIKELY(jackFramesAvailable > 0)) {
577 numFramesToWrite = jackFramesAvailable;
578 jackd->frames_written += numFramesToWrite;
579 jackFramesAvailable = 0;
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;
591 * afile->achans * (afile->asampsize / 8);
592 else jackd->seek_end = afile->afilesize;
594 if (jackd->seek_end > afile->afilesize) jackd->seek_end = afile->afilesize;
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;
614 if (cache_buffer) eof = cache_buffer->
eof;
616 if ((shrink_factor = (
float)in_frames / (
float)jackFramesAvailable) >= 0.f) {
617 jackd->seek_pos += in_bytes;
619 if (eof || (jackd->seek_pos >= jackd->seek_end && !afile->opening)) {
623 jackd->in_use =
FALSE;
629 jackd->sample_in_rate = -jackd->sample_in_rate;
630 afile->adirection = -afile->adirection;
631 jackd->seek_pos -= (jackd->seek_pos - jackd->seek_end);
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;
645 (int64_t)((
double)(afile->start - 1.) / afile->fps * afile->arps)
646 * afile->achans * (afile->asampsize / 8) : 0);
649 if ((jackd->seek_pos -= in_bytes) < seek_start) {
656 jackd->in_use =
FALSE;
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;
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;
669 fwd_seek_pos = jackd->real_seek_pos = jackd->seek_pos;
675 if (jackd->mute || !cache_buffer ||
681 push_cache_buffer(cache_buffer, jackd, in_bytes, nframes, shrink_factor);
683 output_silence(0, nframes, jackd, out_buffer);
690 in_bytes = jackFramesAvailable * jackd->num_output_channels * 4;
691 xin_bytes = in_bytes;
694 if (!jackd->in_use || in_bytes == 0) {
696 output_silence(0, nframes, jackd, out_buffer);
698 jackd->is_silent =
TRUE;
700 if (jackd->seek_pos < 0. && jackd->playing_file > -1 && xfile) {
707 inputFramesAvailable = cache_buffer->
samp_space;
708 else inputFramesAvailable = jackFramesAvailable;
711 lives_printerr(
"%d inputFramesAvailable == %ld, %ld %ld,jackFramesAvailable == %ld\n", inputFramesAvailable,
712 in_frames, jackd->sample_in_rate, jackd->sample_out_rate, jackFramesAvailable);
716 numFramesToWrite = MIN(jackFramesAvailable, inputFramesAvailable);
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);
724 jackd->frames_written += numFramesToWrite;
725 jackFramesAvailable -= numFramesToWrite;
728 lives_printerr(
"jackFramesAvailable == %ld\n", jackFramesAvailable);
735 if (numFramesToWrite > 0) {
740 float *fbuffer = NULL;
747 jackd->sample_out_rate, numFramesToWrite,
TRUE)) {
755 output_silence(0, numFramesToWrite, jackd, out_buffer);
757 for (i = 0; i < jackd->num_output_channels; i++) {
773 jackd->num_output_channels, numFramesToWrite);
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));
800 rbytes = audio_read_inner(jackd, out_buffer,
mainw->
ascrap_file, numFramesToWrite, 1.0,
802 out_unsigned, rbytes);
808 if (wait_cache_buffer) {
809 while (!cache_buffer->
is_ready && !cache_buffer->
die) {
812 wait_cache_buffer =
FALSE;
816 if (!cache_buffer->
die) {
818 for (i = 0; i < jackd->num_output_channels; i++) {
835 weed_set_voidptr_array(layer, WEED_LEAF_AUDIO_DATA, jackd->num_output_channels, (
void **)out_buffer);
837 jackd->num_output_channels, numFramesToWrite);
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));
860 output_silence(0, numFramesToWrite, jackd, out_buffer);
864 if (jackd->astream_fd != -1) {
868 nbytes = numFramesToWrite * jackd->num_output_channels * 4;
869 rbytes = numFramesToWrite * jackd->num_output_channels * 2;
873 check_zero_buff(rbytes);
877 xbuf = (
unsigned char *)cache_buffer->
buffer16[0];
880 float **fp = (
float **)
lives_malloc(jackd->num_output_channels *
sizeof(
float *));
881 for (i = 0; i < jackd->num_output_channels; i++) {
884 xbuf = (
unsigned char *)
lives_malloc(nbytes * jackd->num_output_channels);
886 jackd->num_output_channels, 16, 0,
TRUE,
TRUE, 1.0);
889 if (jackd->num_output_channels != 2) {
891 size_t bysize = 4, tsize = 0;
892 unsigned char *inbuf, *oinbuf = NULL;
895 inbuf = (
unsigned char *)cache_buffer->
buffer16[0];
896 else oinbuf = inbuf = xbuf;
901 rbytes = numFramesToWrite * jackd->num_output_channels * 2;
902 if (check_zero_buff(rbytes))
906 if (jackd->num_output_channels == 1) bysize = 2;
919 inbuf += jackd->num_output_channels * 4;
922 nbytes = numFramesToWrite * jackd->num_output_channels * 4;
927 rbytes = numFramesToWrite * jackd->num_output_channels * 2;
936 output_silence(0, numFramesToWrite, jackd, out_buffer);
940 if (jackd->read_abuf > -1 && !jackd->mute) {
943 if (jackd->astream_fd != -1) {
945 unsigned char *xbuf = (
unsigned char *)out_buffer;
946 nbytes = numFramesToWrite * jackd->num_output_channels * 4;
948 if (jackd->num_output_channels != 2) {
950 size_t bysize = 4, tsize = 0;
951 unsigned char *inbuf = (
unsigned char *)out_buffer;
954 output_silence(0, numFramesToWrite, jackd, out_buffer);
958 if (jackd->num_output_channels == 1) bysize = 2;
971 inbuf += jackd->num_output_channels * 4;
974 nbytes = numFramesToWrite * jackd->num_output_channels * 2;
976 rbytes = numFramesToWrite * jackd->num_output_channels * 2;
978 if (xbuf != (
unsigned char *)out_buffer)
lives_free(xbuf);
982 output_silence(0, numFramesToWrite, jackd, out_buffer);
987 output_silence(nframes - jackFramesAvailable, jackFramesAvailable, jackd, out_buffer);
988 jackFramesAvailable = 0;
996 push_cache_buffer(cache_buffer, jackd, in_bytes, nframes, shrink_factor);
1000 if (shrink_factor > 0.) jackd->seek_pos += xin_bytes / 4 * jackd->bytes_per_channel;
1010 if (jackFramesAvailable > 0) {
1013 lives_printerr(
"buffer underrun of %ld frames\n", jackFramesAvailable);
1015 output_silence(nframes - jackFramesAvailable, jackFramesAvailable, jackd, out_buffer);
1017 }
else if (jackd->state == JackTransportStarting || jackd->state == JackTransportStopped ||
1018 jackd->state == JackTClosed || jackd->state == JackTReset) {
1020 lives_printerr(
"PAUSED or STOPPED or CLOSED, outputting silence\n");
1024 output_silence(0, nframes, jackd, out_buffer);
1025 jackd->is_silent =
TRUE;
1029 if (jackd->state == JackTReset) {
1030 jackd->state = (jack_transport_state_t)JackTStopped;
1035 lives_printerr(
"done\n");
1042int lives_start_ready_callback(jack_transport_state_t state, jack_position_t *pos,
void *arg) {
1061 if (!jack_transport_client)
return TRUE;
1078 if (state != JackTransportStarting)
return TRUE;
1089size_t jack_flush_read_data(
size_t rbytes,
void *data) {
1118static 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) {
1131 frames_out = (int64_t)((
double)nframes / out_scale + 1.);
1135 if (!holding_buff)
return 0;
1149 if (jrb < JACK_READ_BYTES && (
mainw->
rec_samples == -1 || frames_out < mainw->rec_samples)) {
1151 lives_memcpy(&jrbuf[jrb - rbytes], holding_buff, rbytes);
1156 if (jrb <= JACK_READ_BYTES * 2) {
1157 lives_memcpy(&jrbuf[jrb - rbytes], holding_buff, rbytes);
1158 jack_flush_read_data(jrb, jrbuf);
1160 if (jrb > rbytes) jack_flush_read_data(jrb - rbytes, jrbuf);
1161 jack_flush_read_data(rbytes, holding_buff);
1170static int audio_read(nframes_t nframes,
void *arg) {
1180 jack_driver_t *jackd = (jack_driver_t *)arg;
1181 float *in_buffer[jackd->num_input_channels];
1189 if (!jackd->in_use)
return 0;
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];
1205 jackd->frames_written += nframes;
1219 for (i = 0; i < jackd->num_input_channels; i++) {
1235 jack_flush_read_data(jrb, jrbuf);
1246 out_scale = (float)afile->arate / (
float)jackd->sample_in_rate;
1250 rbytes = audio_read_inner(jackd, in_buffer, jackd->playing_file, nframes, out_scale, jackd->reverse_endian,
1251 out_unsigned, rbytes);
1257 jackd->seek_pos += rbytes;
1267int jack_get_srate(nframes_t nframes,
void *arg) {
1274void jack_shutdown(
void *arg) {
1275 jack_driver_t *jackd = (jack_driver_t *)arg;
1277 jackd->client = NULL;
1278 jackd->jackd_died =
TRUE;
1281 lives_printerr(
"jack shutdown, setting client to 0 and jackd_died to true\n");
1282 lives_printerr(
"trying to reconnect right now\n");
1293 if (
mainw->
jackd->playing_file != -1 && afile)
1298static void jack_reset_driver(jack_driver_t *jackd) {
1300 jackd->state = (jack_transport_state_t)JackTReset;
1304void jack_close_device(jack_driver_t *jackd) {
1308 if (jackd->client) {
1309 jack_deactivate(jackd->client);
1311 jack_client_close(jackd->client);
1314 jack_reset_driver(jackd);
1315 jackd->client = NULL;
1317 jackd->is_active =
FALSE;
1329static void jack_error_func(
const char *desc) {
1330 lives_printerr(
"Jack audio error %s\n", desc);
1335boolean 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;
1346 jackd->is_active =
FALSE;
1349 jack_set_error_function(jack_error_func);
1350 jackd->client = NULL;
1361 jackd->client = jack_client_open(client_name, options, &status, server_name);
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"));
1379 if (status & JackNameNotUnique) {
1380 client_name = jack_get_client_name(jackd->client);
1381 lives_printerr(
"unique name `%s' assigned\n", client_name);
1384 jackd->sample_out_rate = jackd->sample_in_rate = jack_get_sample_rate(jackd->client);
1388 for (i = 0; i < jackd->num_output_channels; i++) {
1390 lives_snprintf(portname, 32,
"out_%d", i);
1392#ifdef DEBUG_JACK_PORTS
1393 lives_printerr(
"output port %d is named '%s'\n", i, portname);
1396 jackd->output_port[i] = jack_port_register(jackd->client, portname,
1397 JACK_DEFAULT_AUDIO_TYPE,
1398 JackPortIsOutput | JackPortIsTerminal,
1401 if (!jackd->output_port[i]) {
1402 lives_printerr(
"nay more JACK output ports available\n");
1405 jackd->out_chans_available++;
1410 jack_set_sample_rate_callback(jackd->client, jack_get_srate, jackd);
1415 jack_on_shutdown(jackd->client, jack_shutdown, jackd);
1417 jack_set_process_callback((jack_client_t *)jackd->client, audio_process, jackd);
1423boolean jack_create_client_reader(jack_driver_t *jackd) {
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;
1431 jackd->is_active =
FALSE;
1434 jack_set_error_function(jack_error_func);
1435 jackd->client = NULL;
1438 while (!jackd->client)
1439 jackd->client = jack_client_open(client_name, options, &status, server_name);
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"));
1449 if (status & JackNameNotUnique) {
1450 client_name = jack_get_client_name(jackd->client);
1451 lives_printerr(
"unique name `%s' assigned\n", client_name);
1454 jackd->sample_in_rate = jackd->sample_out_rate = jack_get_sample_rate(jackd->client);
1459 for (i = 0; i < jackd->num_input_channels; i++) {
1461 lives_snprintf(portname, 32,
"in_%d", i);
1463#ifdef DEBUG_JACK_PORTS
1464 lives_printerr(
"input port %d is named '%s'\n", i, portname);
1466 jackd->input_port[i] = jack_port_register(jackd->client, portname,
1467 JACK_DEFAULT_AUDIO_TYPE,
1468 JackPortIsInput | JackPortIsTerminal,
1470 if (!jackd->input_port[i]) {
1471 lives_printerr(
"ne more JACK input ports available\n");
1478 jack_set_sample_rate_callback(jackd->client, jack_get_srate, jackd);
1483 jack_on_shutdown(jackd->client, jack_shutdown, jackd);
1487 jack_set_process_callback(jackd->client, audio_read, jackd);
1493boolean jack_write_driver_activate(jack_driver_t *jackd) {
1497 boolean failed =
FALSE;
1499 if (jackd->is_active)
return TRUE;
1502 if (jack_activate(jackd->client)) {
1503 LIVES_ERROR(
"Cannot activate jack writer client");
1508 jackd->jack_port_flags |= JackPortIsInput;
1510 ports = jack_get_ports(jackd->client, NULL, NULL, jackd->jack_port_flags);
1517 for (i = 0; ports[i]; i++) {
1518#ifdef DEBUG_JACK_PORTS
1519 lives_printerr(
"ports[%d] = '%s'\n", i, ports[i]);
1522 jackd->in_chans_available = i;
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);
1529 LIVES_ERROR(
"Not enough jack input ports available !");
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]);
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]);
1543 LIVES_ERROR(
"Cannot connect all our jack outputs");
1552 LIVES_ERROR(
"Jack writer creation failed, closing and returning error");
1553 jack_close_device(jackd);
1560 jackd->is_active =
TRUE;
1561 jackd->jackd_died =
FALSE;
1562 jackd->in_use =
FALSE;
1563 jackd->is_paused =
FALSE;
1565 d_print(
_(
"Started jack audio subsystem.\n"));
1571boolean jack_read_driver_activate(jack_driver_t *jackd,
boolean autocon) {
1574 boolean failed =
FALSE;
1577 if (!jackd->is_active) {
1578 if (jack_activate(jackd->client)) {
1579 LIVES_ERROR(
"Cannot activate jack reader client");
1587 jackd->jack_port_flags |= JackPortIsOutput;
1589 ports = jack_get_ports(jackd->client, NULL, NULL, jackd->jack_port_flags);
1596 for (i = 0; ports[i]; i++) {
1597#ifdef DEBUG_JACK_PORTS
1598 lives_printerr(
"ports[%d] = '%s'\n", i, ports[i]);
1601 jackd->out_chans_available = i;
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);
1608 LIVES_ERROR(
"Not enough jack output ports available !");
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]);
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]);
1620 LIVES_ERROR(
"Cannot connect all our jack inputs");
1628 lives_printerr(
"Failed, closing and returning error\n");
1629 jack_close_device(jackd);
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"));
1653jack_driver_t *jack_get_driver(
int dev_idx,
boolean is_output) {
1654 jack_driver_t *jackd;
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);
1666int jack_audio_init(
void) {
1669 jack_driver_t *jackd;
1671 for (i = 0; i < JACK_MAX_OUTDEVICES; 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;
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;
1700int jack_audio_read_init(
void) {
1702 jack_driver_t *jackd;
1704 for (i = 0; i < JACK_MAX_INDEVICES; 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;
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;
1737void 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;
1746ticks_t lives_jack_get_time(jack_driver_t *jackd) {
1749 jack_nframes_t frames, retframes;
1750 static jack_nframes_t last_frames = 0;
1752 if (!jackd->client)
return -1;
1757 while ((timeout =
lives_alarm_check(alarm_handle)) > 0 && jack_get_msgq(jackd)) {
1762 if (timeout == 0)
return -1;
1765 frames = jack_frame_time(jackd->client);
1768 if (last_frames > 0 && frames <= last_frames) {
1769 retframes += jackd->frames_written;
1770 }
else jackd->frames_written = 0;
1771 last_frames = frames;
1773 return (
ticks_t)((frames - jackd->nframes_start) * (1000000. / jack_get_sample_rate(
1778double lives_jack_get_pos(jack_driver_t *jackd) {
1780 if (jackd->playing_file > -1)
1781 return fwd_seek_pos / (double)(afile->arps * afile->achans * afile->asampsize / 8);
1783 return (
double)jackd->frames_written / (double)jackd->sample_out_rate;
1788boolean jack_audio_seek_frame(jack_driver_t *jackd,
double frame) {
1795 double thresh = 0., delta = 0.;
1800 if (frame < 1) frame = 1;
1803 jmsg = jack_get_msgq(jackd);
1806 if (timeout == 0 || jackd->playing_file == -1) {
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);
1813 (afile->asampsize / 8));
1814 thresh = 1. / (double)afile->fps;
1816 if (delta >= thresh || delta <= -thresh)
1817 jack_audio_seek_bytes(jackd, seekstart, afile);
1822int64_t jack_audio_seek_bytes(jack_driver_t *jackd, int64_t bytes,
lives_clip_t *sfile) {
1834 fwd_seek_pos = bytes;
1838 if (alarm_handle == -1) {
1843 if (jackd->in_use) {
1845 jmsg = jack_get_msgq(jackd);
1848 if (timeout == 0 || jackd->playing_file == -1) {
1849 if (timeout == 0)
LIVES_WARN(
"Jack connect timed out");
1857 if (seekstart < 0) seekstart = 0;
1861 jack_message2.next = NULL;
1863 if (!jackd->msgq) jackd->msgq = &jack_message2;
1864 else jackd->msgq->next = &jack_message2;
1869boolean jack_try_reconnect(
void) {
1871 jack_audio_read_init();
1875 if (!jack_create_client_writer(
mainw->
jackd))
goto err123;
1877 d_print(
_(
"\nConnection to jack audio was reset.\n"));
1888void jack_pb_end(
void) {
1889 cache_buffer = NULL;
1893void jack_aud_pb_ready(
int fileno) {
1902 char *tmpfilename = NULL;
1939 if (timeout == 0) jack_try_reconnect();
1947 jack_message.next = NULL;
void append_to_audio_bufferf(float *src, uint64_t nsamples, int channum)
boolean get_audio_from_plugin(float **fbuffer, int nchans, int arate, int nsamps, boolean is_audio_thread)
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
void wake_audio_thread(void)
LIVES_GLOBAL_INLINE void audio_stream(void *buff, size_t nbytes, int fd)
void sample_silence_stream(int nchans, int64_t nframes)
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...
LIVES_GLOBAL_INLINE lives_audio_buf_t * audio_cache_get_buffer(void)
float sample_move_d16_float(float *dst, short *src, uint64_t nsamples, uint64_t src_skip, int is_unsigned, boolean rev_endian, float vol)
LIVES_GLOBAL_INLINE char * lives_get_audio_file_name(int fnum)
LIVES_GLOBAL_INLINE void sample_silence_dS(float *dst, uint64_t nsamples)
#define AUD_WRITE_CHECK
after recording this many bytes we check disk space (default 128MB)
#define ASERVER_CMD_FILE_SEEK
#define ASERVER_CMD_PROCESSED
asynch msging
#define WEED_LEAF_HOST_KEEP_ADATA
#define ASERVER_CMD_FILE_CLOSE
#define lives_vol_from_linear(vol)
#define SWAP_X_TO_L
endian swapping
#define ASERVER_CMD_FILE_OPEN
void on_playall_activate(LiVESMenuItem *menuitem, livespointer user_data)
boolean clip_can_reverse(int clipno)
void on_stop_activate(LiVESMenuItem *menuitem, livespointer user_data)
LIVES_GLOBAL_INLINE weed_layer_t * weed_layer_free(weed_layer_t *layer)
frees pixel_data for a layer, then the layer itself
LIVES_GLOBAL_INLINE weed_layer_t * weed_layer_new(int layer_type)
LIVES_GLOBAL_INLINE float ** weed_layer_get_audio_data(weed_layer_t *layer, int *naudchans)
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)
#define WEED_LAYER_TYPE_AUDIO
weed_plant_t weed_layer_t
LIVES_GLOBAL_INLINE void do_jack_lost_conn_error(void)
void weed_apply_audio_effects_rt(weed_layer_t *alayer, weed_timecode_t tc, boolean analysers_only, boolean is_audio_thread)
boolean has_audio_filters(lives_af_t af_type)
LIVES_GLOBAL_INLINE ticks_t lives_get_current_ticks(void)
LIVES_GLOBAL_INLINE uint64_t fastrand(void)
void defer_sigint(int signum)
void catch_sigint(int signum)
void set_signal_handlers(SignalHandlerPointer sigfunc)
boolean lives_unsetenv(const char *name)
boolean check_for_disk_space(boolean fullcheck)
void(* SignalHandlerPointer)(int)
ticks_t lives_get_current_playback_ticks(ticks_t origsecs, ticks_t origusecs, lives_time_source_t *time_source)
int lives_chmod(const char *target, const char *mode)
boolean lives_setenv(const char *name, const char *value)
#define ALIGN_CEIL64(a, b)
boolean lives_alarm_clear(lives_alarm_t alarm_handle)
#define LIVES_LOCAL_INLINE
int lives_system(const char *com, boolean allow_error)
void add_to_ascrap_mb(uint64_t bytes)
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 ...
#define IS_VALID_CLIP(clip)
void get_location(const char *exe, char *val, int maxlen)
off_t lives_buffered_offset(int fd)
char * filename_from_fd(char *val, int fd)
: return filename from an open fd, freeing val first
void d_print(const char *fmt,...)
boolean lives_freep(void **ptr)
ticks_t lives_alarm_check(lives_alarm_t alarm_handle)
@ CANCEL_AUD_END
video playback completed
@ CANCEL_KEEP
user pressed 'Keep'
#define LIVES_SHORT_TIMEOUT
#define EXEC_JACKD
recommended if (!have_pulseaudio)
#define USEC_TO_TICKS
multiplying factor uSec -> ticks_t (def. 100)
#define TICKS_PER_SECOND_DBL
actually microseconds / 100.
#define SCRATCH_JUMP
jump and resync audio
#define LIVES_DEFAULT_TIMEOUT
void mt_tl_move(lives_mt *mt, double pos)
#define JACK_OPTS_TRANSPORT_CLIENT
jack can start/stop
#define AUDIO_OPTS_FOLLOW_CLIPS
#define JACK_OPTS_TIMEBASE_CLIENT
full timebase client
#define JACK_OPTS_START_TSERVER
start transport server
#define AUDIO_OPTS_FOLLOW_FPS
#define JACK_OPTS_TRANSPORT_MASTER
transport master
#define JACK_OPTS_TIMEBASE_LSTART
LiVES sets play start position.
_future_prefs * future_prefs
#define JACK_OPTS_START_ASERVER
start audio server
#define JACK_OPTS_NO_READ_AUTOCON
do not auto con. rd clients when playing ext aud
volatile float volume
audio volume level (for jack and pulse)
volatile uint32_t audio_opts
boolean force_system_clock
char jack_aserver[PATH_MAX]
boolean(* render_audio_frame_float)(float **audio, int nsamps)
volatile struct _aserver_message_t * next
short ** buffer16
sample data in 16 bit format (or NULL)
lives_operation_t operation
float ** bufferf
sample data in float format (or NULL)
boolean eof
did we read EOF ? [readonly by client]
volatile boolean is_ready
int in_achans
channels for _filebuffer side
volatile size_t samples_filled
number of samples filled (readonly client)
int out_achans
channels for buffer* side
volatile boolean die
set to TRUE to shut down thread
boolean sequential
hint that we will read sequentially starting from seek
size_t samp_space
buffer space in samples (* by sizeof(type) to get bytesize) [if interleaf, also * by chans]
double shrink_factor
resampling ratio
corresponds to one clip in the GUI
int arps
audio physical sample rate (i.e the "normal" sample rate of the clip when played at 1,...
int asampsize
audio sample size in bits (8 or 16)
volatile off64_t aseek_pos
audio seek posn. (bytes) for when we switch clips
int achans
number of audio channels (0, 1 or 2)
int cb_src
source clip for clipboard; for other clips, may be used to hold some temporary linkage
uint32_t signed_endian
bitfield
int arate
current audio playback rate (varies if the clip rate is changed)
_vid_playback_plugin * vpp
video plugin
volatile int agen_key
which fx key is generating audio [1 based] (or 0 for none)
volatile boolean video_seek_ready
pthread_mutex_t audio_filewriteend_mutex
sync for ending writing audio to file
int aud_rec_fd
fd of file we are recording audio to
volatile ticks_t currticks
wall clock time, updated whenever lives_get_*_ticks is called
lives_clip_t * files[MAX_FILES+1]
+1 for the clipboard
ticks_t origsecs
playback start seconds - subtracted from all other ticks to keep numbers smaller
volatile boolean loop_cont
volatile boolean ext_audio
using external video playback plugin to stream audio
volatile lives_cancel_t cancelled
pthread_cond_t avseek_cond
ticks_t orignsecs
usecs at start of playback - ditto
void * jackd
jack audio player / transport
uint64_t aud_data_written
frames_t fps_mini_measure
show fps stats during playback
pthread_mutex_t vpp_stream_mutex
prevent from writing audio when stream is closing
volatile int rec_aclip
recording values - to be inserted at the following video frame
volatile double rec_aseek
boolean playing_sel
list of set names in current workdir, mau be NULL
LiVESWidget * ext_audio_mon
volatile boolean record_paused
pause during recording
int ascrap_file
scrap file for recording audio scraps
lives_mt * multitrack
holds a pointer to the entire multitrack environment; NULL in Clip Edit mode
pthread_mutex_t avseek_mutex
volatile boolean ping_pong
volatile boolean agen_needs_reinit
pthread_mutex_t cache_buffer_mutex
sync for jack playback termination
boolean is_processing
states
ticks_t deltaticks
deltaticks for scratching
volatile ticks_t startticks
effective ticks when current frame was (should have been) displayed
volatile boolean audio_seek_ready
volatile lives_whentostop_t whentostop
int playing_file
which number file we are playing (or -1) [generally mainw->current_file]
volatile lives_audio_buf_t * audio_frame_buffer
used for buffering / feeding audio to video generators
volatile int uflow_count
experimental values, primarily for testing
weed_event_t * event_list
current event_list, for recording
#define lives_strdup_printf(fmt,...)