26 #include <sys/types.h>
35 #include "JackConstants.h"
36 #include "JackPlatformPlug.h"
38 #include "JackControlAPIAndroid.h"
41 #if defined(JACK_DBUS) && defined(__linux__)
43 #include <dbus/dbus.h>
44 #include "audio_reserve.h"
48 #include <systemd/sd-daemon.h>
59 #include <CoreFoundation/CFNotificationCenter.h>
60 #include <CoreFoundation/CoreFoundation.h>
62 static void notify_server_start(
const char* server_name)
65 CFStringRef ref = CFStringCreateWithCString(NULL, server_name, kCFStringEncodingMacRoman);
66 CFNotificationCenterPostNotificationWithOptions(CFNotificationCenterGetDistributedCenter(),
67 CFSTR(
"com.grame.jackserver.start"),
70 kCFNotificationDeliverImmediately | kCFNotificationPostToAllSessions);
74 static void notify_server_stop(
const char* server_name)
77 CFStringRef ref1 = CFStringCreateWithCString(NULL, server_name, kCFStringEncodingMacRoman);
78 CFNotificationCenterPostNotificationWithOptions(CFNotificationCenterGetDistributedCenter(),
79 CFSTR(
"com.grame.jackserver.stop"),
82 kCFNotificationDeliverImmediately | kCFNotificationPostToAllSessions);
88 static void notify_server_start(
const char* server_name)
90 static void notify_server_stop(
const char* server_name)
95 static void copyright(FILE* file)
97 fprintf(file,
"jackdmp " VERSION
"\n"
98 "Copyright 2001-2005 Paul Davis and others.\n"
99 "Copyright 2004-2016 Grame.\n"
100 "Copyright 2016-2019 Filipe Coelho.\n"
101 "jackdmp comes with ABSOLUTELY NO WARRANTY\n"
102 "This is free software, and you are welcome to redistribute it\n"
103 "under certain conditions; see the file COPYING for details\n");
114 node_ptr = jack_slist_next(node_ptr);
128 node_ptr = jack_slist_next(node_ptr);
136 while (parameters_list) {
140 parameters_list = jack_slist_next(parameters_list);
147 static void jackctl_server_switch_master_dummy(
jackctl_server_t * server_ctl,
char * master_driver_name)
149 static bool is_dummy_driver =
false;
150 if(!strcmp(master_driver_name,
"dummy")) {
154 if(is_dummy_driver) {
155 is_dummy_driver =
false;
156 driver_ctr = jackctl_server_get_driver(server_ctl, master_driver_name);
158 is_dummy_driver =
true;
159 driver_ctr = jackctl_server_get_driver(server_ctl,
"dummy");
169 fprintf(file,
"Available backends:\n");
174 node_ptr = jack_slist_next(node_ptr);
183 fprintf(file,
"Available internals:\n");
188 node_ptr = jack_slist_next(node_ptr);
196 const JSList * server_parameters;
201 "Usage: jackdmp [ --no-realtime OR -r ]\n"
202 " [ --realtime OR -R [ --realtime-priority OR -P priority ] ]\n"
203 " (the two previous arguments are mutually exclusive. The default is --realtime)\n"
204 " [ --name OR -n server-name ]\n"
205 " [ --timeout OR -t client-timeout-in-msecs ]\n"
206 " [ --loopback OR -L loopback-port-number ]\n"
207 " [ --port-max OR -p maximum-number-of-ports]\n"
208 " [ --slave-backend OR -X slave-backend-name ]\n"
209 " [ --internal-client OR -I internal-client-name ]\n"
210 " [ --internal-session-file OR -C internal-session-file ]\n"
211 " [ --verbose OR -v ]\n"
213 " [ --clocksource OR -c [ h(pet) | s(ystem) ]\n"
215 " [ --autoconnect OR -a <modechar>]\n");
218 param = jackctl_get_parameter(server_parameters,
"self-connect-mode");
220 " where <modechar> is one of:\n");
225 if (value.c == JACK_DEFAULT_SELF_CONNECT_MODE)
227 fprintf(file,
" (default)");
233 " [ --replace-registry ]\n"
234 " [ --silent OR -s ]\n"
235 " [ --sync OR -S ]\n"
236 " [ --temporary OR -T ]\n"
237 " [ --version OR -V ]\n"
238 " -d master-backend-name [ ... master-backend args ... ]\n"
239 " jackdmp -d master-backend-name --help\n"
240 " to display options for each master backend\n\n");
243 print_server_drivers(server, file);
244 print_server_internals(server, file);
249 extern "C" void silent_jack_error_callback(
const char *desc);
253 printf(
"jackdmp version " VERSION
" tmpdir "
254 jack_server_dir
" protocol %d" "\n",
255 JACK_PROTOCOL_VERSION);
260 int main(
int argc,
char** argv)
263 const JSList * server_parameters;
264 const char* server_name = JACK_DEFAULT_SERVER_NAME;
267 int replace_registry = 0;
269 for(
int a = 1; a < argc; ++a) {
270 if( !strcmp(argv[a],
"--version") || !strcmp(argv[a],
"-V") ) {
274 const char *options =
"-d:X:I:P:uvshrRL:STFl:t:mn:p:C:"
281 struct option long_options[] = {
283 {
"clock-source", 1, 0,
'c' },
285 {
"internal-session-file", 1, 0,
'C' },
286 {
"loopback-driver", 1, 0,
'L' },
287 {
"audio-driver", 1, 0,
'd' },
288 {
"midi-driver", 1, 0,
'X' },
289 {
"internal-client", 1, 0,
'I' },
290 {
"verbose", 0, 0,
'v' },
291 {
"help", 0, 0,
'h' },
292 {
"port-max", 1, 0,
'p' },
293 {
"no-mlock", 0, 0,
'm' },
294 {
"name", 1, 0,
'n' },
295 {
"unlock", 0, 0,
'u' },
296 {
"realtime", 0, 0,
'R' },
297 {
"no-realtime", 0, 0,
'r' },
298 {
"replace-registry", 0, &replace_registry, 0 },
299 {
"loopback", 0, 0,
'L' },
300 {
"realtime-priority", 1, 0,
'P' },
301 {
"timeout", 1, 0,
't' },
302 {
"temporary", 0, 0,
'T' },
303 {
"silent", 0, 0,
's' },
304 {
"sync", 0, 0,
'S' },
305 {
"autoconnect", 1, 0,
'a' },
310 int option_index = 0;
311 char* internal_session_file = NULL;
312 char* master_driver_name = NULL;
313 char** master_driver_args = NULL;
314 int master_driver_nargs = 1;
320 std::list<char*> internals_list;
321 std::list<char*> slaves_list;
322 std::list<char*>::iterator it;
325 int return_value = -1;
326 bool notify_sent =
false;
329 #if defined(JACK_DBUS) && defined(__linux__)
330 if (getenv(
"JACK_NO_AUDIO_RESERVATION"))
337 if (server_ctl == NULL) {
338 fprintf(stderr,
"Failed to create server object\n");
345 while (!master_driver_name &&
346 (opt = getopt_long(argc, argv, options,
347 long_options, &option_index)) != EOF) {
352 param = jackctl_get_parameter(server_parameters,
"clock-source");
354 if (tolower (optarg[0]) ==
'h') {
355 value.ui = JACK_TIMER_HPET;
357 }
else if (tolower (optarg[0]) ==
'c') {
362 value.ui = JACK_TIMER_SYSTEM_CLOCK;
364 }
else if (tolower (optarg[0]) ==
's') {
365 value.ui = JACK_TIMER_SYSTEM_CLOCK;
368 usage(stdout, server_ctl);
376 param = jackctl_get_parameter(server_parameters,
"self-connect-mode");
378 bool value_valid =
false;
381 if( value.c == optarg[0] )
389 usage(stdout, server_ctl);
396 master_driver_name = optarg;
400 loopback = atoi(optarg);
404 slaves_list.push_back(optarg);
408 internals_list.push_back(optarg);
412 param = jackctl_get_parameter(server_parameters,
"port-max");
414 value.ui = atoi(optarg);
426 param = jackctl_get_parameter(server_parameters,
"verbose");
438 param = jackctl_get_parameter(server_parameters,
"sync");
446 server_name = optarg;
447 param = jackctl_get_parameter(server_parameters,
"name");
455 internal_session_file = optarg;
459 param = jackctl_get_parameter(server_parameters,
"realtime-priority");
461 value.i = atoi(optarg);
467 param = jackctl_get_parameter(server_parameters,
"realtime");
475 param = jackctl_get_parameter(server_parameters,
"realtime");
483 param = jackctl_get_parameter(server_parameters,
"temporary");
491 param = jackctl_get_parameter(server_parameters,
"client-timeout");
493 value.i = atoi(optarg);
499 fprintf(stderr,
"unknown option character %c\n", optopt);
503 usage(stdout, server_ctl);
509 param = jackctl_get_parameter(server_parameters,
"replace-registry");
511 value.b = replace_registry;
515 if (!master_driver_name) {
516 usage(stderr, server_ctl,
false);
521 master_driver_ctl = jackctl_server_get_driver(server_ctl, master_driver_name);
522 if (master_driver_ctl == NULL) {
523 fprintf(stderr,
"Unknown driver \"%s\"\n", master_driver_name);
528 fprintf(stderr,
"Driver \"%s\" is not a master \n", master_driver_name);
533 master_driver_nargs = 1 + argc - optind;
535 master_driver_nargs = 1;
538 if (master_driver_nargs == 0) {
539 fprintf(stderr,
"No driver specified ... hmm. JACK won't do"
540 " anything when run like this.\n");
544 master_driver_args = (
char **) malloc(
sizeof(
char *) * master_driver_nargs);
545 master_driver_args[0] = master_driver_name;
547 for (i = 1; i < master_driver_nargs; i++) {
548 master_driver_args[
i] = argv[optind++];
560 fprintf(stderr,
"Failed to open server\n");
565 for (it = slaves_list.begin(); it != slaves_list.end(); it++) {
566 jackctl_driver_t * slave_driver_ctl = jackctl_server_get_driver(server_ctl, *it);
567 if (slave_driver_ctl == NULL) {
568 fprintf(stderr,
"Unknown driver \"%s\"\n", *it);
572 fprintf(stderr,
"Driver \"%s\" is not a slave \n", *it);
576 fprintf(stderr,
"Driver \"%s\" cannot be loaded\n", *it);
583 loopback_driver_ctl = jackctl_server_get_driver(server_ctl,
"loopback");
585 if (loopback_driver_ctl != NULL) {
587 param = jackctl_get_parameter(loopback_parameters,
"channels");
593 fprintf(stderr,
"Driver \"loopback\" cannot be loaded\n");
597 fprintf(stderr,
"Driver \"loopback\" not found\n");
604 fprintf(stderr,
"Failed to start server\n");
609 for (it = internals_list.begin(); it != internals_list.end(); it++) {
610 jackctl_internal_t * internal_driver_ctl = jackctl_server_get_internal(server_ctl, *it);
611 if (internal_driver_ctl == NULL) {
612 fprintf(stderr,
"Unknown internal \"%s\"\n", *it);
616 fprintf(stderr,
"Internal client \"%s\" cannot be loaded\n", *it);
621 if (internal_session_file != NULL) {
623 fprintf(stderr,
"Internal session file %s cannot be loaded!\n", internal_session_file);
628 notify_server_start(server_name);
633 sd_notify(0,
"READY=1");
640 int signal = jackctl_wait_signals_and_return(sigmask);
641 if (signal == SIGUSR2) {
642 jackctl_server_switch_master_dummy(server_ctl, master_driver_name);
652 sd_notify(0,
"STOPPING=1");
657 fprintf(stderr,
"Cannot stop server...\n");
661 if (loopback > 0 && loopback_driver_ctl) {
665 for (it = slaves_list.begin(); it != slaves_list.end(); it++) {
666 jackctl_driver_t * slave_driver_ctl = jackctl_server_get_driver(server_ctl, *it);
667 if (slave_driver_ctl) {
673 for (it = internals_list.begin(); it != internals_list.end(); it++) {
674 jackctl_internal_t * internal_driver_ctl = jackctl_server_get_internal(server_ctl, *it);
675 if (internal_driver_ctl) {
684 notify_server_stop(server_name);
SERVER_EXPORT int jackctl_driver_params_parse(jackctl_driver *driver_ptr, int argc, char *argv[])
SERVER_EXPORT jackctl_sigmask_t * jackctl_setup_signals(unsigned int flags)
SERVER_EXPORT bool jackctl_server_open(jackctl_server *server_ptr, jackctl_driver *driver_ptr)
SERVER_EXPORT jackctl_server_t * jackctl_server_create(bool(*on_device_acquire)(const char *device_name), void(*on_device_release)(const char *device_name))
SERVER_EXPORT bool jackctl_server_switch_master(jackctl_server *server_ptr, jackctl_driver *driver_ptr)
SERVER_EXPORT const char * jackctl_internal_get_name(jackctl_internal *internal_ptr)
int32_t i
member used for JackParamInt
void jack_set_error_function(void(*func)(const char *)) JACK_OPTIONAL_WEAK_EXPORT
SERVER_EXPORT const char * jackctl_parameter_get_name(jackctl_parameter *parameter_ptr)
SERVER_EXPORT bool jackctl_server_stop(jackctl_server *server_ptr)
Type for parameter value.
SERVER_EXPORT const JSList * jackctl_driver_get_parameters(jackctl_driver *driver_ptr)
SERVER_EXPORT bool jackctl_server_close(jackctl_server *server_ptr)
SERVER_EXPORT bool jackctl_server_remove_slave(jackctl_server *server_ptr, jackctl_driver *driver_ptr)
SERVER_EXPORT const char * jackctl_parameter_get_enum_constraint_description(jackctl_parameter *parameter_ptr, uint32_t index)
SERVER_EXPORT const JSList * jackctl_server_get_internals_list(jackctl_server *server_ptr)
SERVER_EXPORT const JSList * jackctl_server_get_drivers_list(jackctl_server *server_ptr)
SERVER_EXPORT bool jackctl_server_start(jackctl_server *server_ptr)
SERVER_EXPORT uint32_t jackctl_parameter_get_enum_constraints_count(jackctl_parameter *parameter_ptr)
SERVER_EXPORT bool jackctl_parameter_set_value(jackctl_parameter *parameter_ptr, const union jackctl_parameter_value *value_ptr)
SERVER_EXPORT bool jackctl_server_add_slave(jackctl_server *server_ptr, jackctl_driver *driver_ptr)
#define JACK_PARAM_STRING_MAX
Max length of string parameter value, excluding terminating null char.
SERVER_EXPORT bool jackctl_server_load_session_file(jackctl_server *server_ptr, const char *file)
SERVER_EXPORT const char * jackctl_driver_get_name(jackctl_driver *driver_ptr)
SERVER_EXPORT union jackctl_parameter_value jackctl_parameter_get_enum_constraint_value(jackctl_parameter *parameter_ptr, uint32_t index)
SERVER_EXPORT bool jackctl_server_unload_internal(jackctl_server *server_ptr, jackctl_internal *internal)
SERVER_EXPORT void jackctl_server_destroy(jackctl_server *server_ptr)
SERVER_EXPORT jackctl_driver_type_t jackctl_driver_get_type(jackctl_driver *driver_ptr)
SERVER_EXPORT const JSList * jackctl_server_get_parameters(jackctl_server *server_ptr)
SERVER_EXPORT void jackctl_wait_signals(jackctl_sigmask_t *sigmask)
SERVER_EXPORT bool jackctl_server_load_internal(jackctl_server *server_ptr, jackctl_internal *internal)