2 Copyright (C) 2001 Paul Davis
3 Copyright (C) 2004-2006 Grame
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include "JackServer.h"
27 #include "JackConstants.h"
28 #include "driver_interface.h"
29 #include "JackDriverLoader.h"
34 static JackServer
* fServer
;
35 static char *server_name
= "default";
36 static int realtime_priority
= 10;
37 static int do_mlock
= 1;
38 static unsigned int port_max
= 128;
39 static int realtime
= 0;
40 static int loopback
= 0;
41 static int temporary
= 0;
42 static int client_timeout
= 0; /* msecs; if zero, use period size. */
43 static int do_unlock
= 0;
44 static JSList
* drivers
= NULL
;
46 static int xverbose
= 0;
48 #define DEFAULT_TMP_DIR "/tmp"
49 char *jack_tmpdir
= DEFAULT_TMP_DIR
;
51 void jack_print_driver_options (jack_driver_desc_t
* desc
, FILE *file
);
52 void jack_print_driver_param_usage (jack_driver_desc_t
* desc
, unsigned long param
, FILE *file
);
53 int jack_parse_driver_params (jack_driver_desc_t
* desc
, int argc
, char* argv
[], JSList
** param_ptr
);
54 static void silent_jack_error_callback (const char *desc
)
57 static void copyright(FILE* file
)
59 fprintf (file
, "jackdmp " VERSION
"\n"
60 "Copyright 2001-2005 Paul Davis and others.\n"
61 "Copyright 2004-2006 Grame.\n"
62 "jackdmp comes with ABSOLUTELY NO WARRANTY\n"
63 "This is free software, and you are welcome to redistribute it\n"
64 "under certain conditions; see the file COPYING for details\n");
67 static void usage (FILE *file
)
71 "usage: jackdmp [ --realtime OR -R [ --realtime-priority OR -P priority ] ]\n"
72 " [ --name OR -n server-name ]\n"
73 // " [ --no-mlock OR -m ]\n"
74 // " [ --unlock OR -u ]\n"
75 " [ --timeout OR -t client-timeout-in-msecs ]\n"
76 " [ --loopback OR -L loopback-port-number ]\n"
77 // " [ --port-max OR -p maximum-number-of-ports]\n"
78 " [ --verbose OR -v ]\n"
79 " [ --silent OR -s ]\n"
81 " [ --version OR -V ]\n"
82 " -d driver [ ... driver args ... ]\n"
83 " where driver can be `alsa', `coreaudio', 'portaudio' or `dummy'\n"
84 " jackdmp -d driver --help\n"
85 " to display options for each driver\n\n");
88 static int JackStart(jack_driver_desc_t
* driver_desc
, JSList
* driver_params
, int sync
, int time_out_ms
, int rt
, int priority
, int loopback
, int verbose
)
90 printf("Jackdmp: sync = %ld timeout = %ld rt = %ld priority = %ld verbose = %ld \n", sync
, time_out_ms
, rt
, priority
, verbose
);
91 fServer
= new JackServer(sync
, time_out_ms
, rt
, priority
, loopback
, verbose
);
92 int res
= fServer
->Open(driver_desc
, driver_params
);
93 return (res
< 0) ? res
: fServer
->Start();
100 printf("Jackdmp: server close\n");
102 printf("Jackdmp: delete server\n");
106 static int JackDelete()
109 printf("Jackdmp: delete server\n");
114 static char* jack_default_server_name(void)
117 if ((server_name = getenv("JACK_DEFAULT_SERVER")) == NULL)
118 server_name = "default";
122 // returns the name of the per-user subdirectory of jack_tmpdir
123 static char* jack_user_dir(void)
125 static char user_dir[PATH_MAX] = "";
127 // format the path name on the first call
128 if (user_dir[0] == '\0') {
129 snprintf (user_dir, sizeof (user_dir), "%s/jack-%d",
130 jack_tmpdir, _getuid ());
136 // returns the name of the per-server subdirectory of jack_user_dir()
138 static char* get_jack_server_dir(const char * toto)
140 static char server_dir[PATH_MAX] = "";
142 // format the path name on the first call
143 if (server_dir[0] == '\0') {
144 snprintf (server_dir, sizeof (server_dir), "%s/%s",
145 jack_user_dir (), server_name);
151 static void jack_cleanup_files (const char *server_name)
154 struct dirent *dirent;
155 char *dir_name = get_jack_server_dir (server_name);
157 // nothing to do if the server directory does not exist
158 if ((dir = opendir (dir_name)) == NULL) {
162 // unlink all the files in this directory, they are mine
163 while ((dirent = readdir (dir)) != NULL) {
165 char fullpath[PATH_MAX];
167 if ((strcmp (dirent->d_name, ".") == 0)
168 || (strcmp (dirent->d_name, "..") == 0)) {
172 snprintf (fullpath, sizeof (fullpath), "%s/%s",
173 dir_name, dirent->d_name);
175 if (unlink (fullpath)) {
176 jack_error ("cannot unlink `%s' (%s)", fullpath,
183 // now, delete the per-server subdirectory, itself
184 if (rmdir (dir_name)) {
185 jack_error ("cannot remove `%s' (%s)", dir_name,
189 // finally, delete the per-user subdirectory, if empty
190 if (rmdir (jack_user_dir ())) {
191 if (errno != ENOTEMPTY) {
192 jack_error ("cannot remove `%s' (%s)",
193 jack_user_dir (), strerror (errno));
199 int main(int argc
, char* argv
[])
201 jack_driver_desc_t
* driver_desc
;
202 const char *options
= "-ad:P:uvshVRL:STFl:t:mn:p:";
203 struct option long_options
[] = {
204 { "driver", 1, 0, 'd'
206 { "verbose", 0, 0, 'v' },
207 { "help", 0, 0, 'h' },
208 { "port-max", 1, 0, 'p' },
209 { "no-mlock", 0, 0, 'm' },
210 { "name", 0, 0, 'n' },
211 { "unlock", 0, 0, 'u' },
212 { "realtime", 0, 0, 'R' },
213 { "loopback", 0, 0, 'L' },
214 { "realtime-priority", 1, 0, 'P' },
215 { "timeout", 1, 0, 't' },
216 { "temporary", 0, 0, 'T' },
217 { "version", 0, 0, 'V' },
218 { "silent", 0, 0, 's' },
219 { "sync", 0, 0, 'S' },
223 int option_index
= 0;
225 char *driver_name
= NULL
;
226 char **driver_args
= NULL
;
227 JSList
* driver_params
;
228 int driver_nargs
= 1;
229 int show_version
= 0;
236 while (!seen_driver
&&
237 (opt
= getopt_long(argc
, argv
, options
,
238 long_options
, &option_index
)) != EOF
) {
243 driver_name
= optarg
;
252 //jack_set_error_function(silent_jack_error_callback);
260 server_name
= optarg
;
268 port_max
= (unsigned int)atol(optarg
);
272 realtime_priority
= atoi(optarg
);
280 loopback
= atoi(optarg
);
288 client_timeout
= atoi(optarg
);
300 fprintf(stderr
, "unknown option character %c\n",
314 drivers
= jack_drivers_load (drivers
);
316 fprintf (stderr
, "jackdmp: no drivers found; exiting\n");
320 driver_desc
= jack_find_driver_descriptor (drivers
, driver_name
);
322 fprintf (stderr
, "jackdmp: unknown driver '%s'\n", driver_name
);
327 driver_nargs
= 1 + argc
- optind
;
332 if (driver_nargs
== 0) {
333 fprintf (stderr
, "No driver specified ... hmm. JACK won't do"
334 " anything when run like this.\n");
338 driver_args
= (char **) malloc (sizeof (char *) * driver_nargs
);
339 driver_args
[0] = driver_name
;
341 for (i
= 1; i
< driver_nargs
; i
++) {
342 driver_args
[i
] = argv
[optind
++];
345 if (jack_parse_driver_params (driver_desc
, driver_nargs
,
346 driver_args
, &driver_params
)) {
350 //if (server_name == NULL)
351 // server_name = jack_default_server_name ();
355 rc
= jack_register_server (server_name
);
358 fprintf (stderr
, "`%s' server already active\n", server_name
);
361 fprintf (stderr
, "too many servers already active\n");
364 fprintf (stderr
, "no access to shm registry\n");
368 fprintf (stderr
, "server `%s' registered\n",
373 /* clean up shared memory and files from any previous
374 * instance of this server name */
376 // jack_cleanup_files(server_name);
378 if (!realtime
&& client_timeout
== 0)
379 client_timeout
= 500; /* 0.5 sec; usable when non realtime. */
381 int res
= JackStart(driver_desc
, driver_params
, sync
, client_timeout
, realtime
, realtime_priority
, loopback
, xverbose
);
383 printf("Cannot start server... exit\n");
388 printf("Type 'q' to quit\n");
390 while ((c
= getchar()) != 'q') {}
395 // jack_cleanup_files(server_name);
396 jack_unregister_server(server_name
);