00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <iostream>
00022 #include <assert.h>
00023 #include <process.h>
00024 #include <getopt.h>
00025 #include <signal.h>
00026
00027 #include "JackServer.h"
00028 #include "JackConstants.h"
00029 #include "driver_interface.h"
00030 #include "JackDriverLoader.h"
00031 #include "shm.h"
00032
00033 using namespace Jack;
00034
00035 static JackServer* fServer;
00036 static char *server_name = "default";
00037 static int realtime_priority = 10;
00038 static int do_mlock = 1;
00039 static unsigned int port_max = 128;
00040 static int realtime = 0;
00041 static int loopback = 0;
00042 static int temporary = 0;
00043 static int client_timeout = 0;
00044 static int do_unlock = 0;
00045 static JSList* drivers = NULL;
00046 static int sync = 0;
00047 static int xverbose = 0;
00048
00049 #define DEFAULT_TMP_DIR "/tmp"
00050 char *jack_tmpdir = DEFAULT_TMP_DIR;
00051
00052 HANDLE waitEvent;
00053
00054 void jack_print_driver_options (jack_driver_desc_t * desc, FILE *file);
00055 void jack_print_driver_param_usage (jack_driver_desc_t * desc, unsigned long param, FILE *file);
00056 int jack_parse_driver_params (jack_driver_desc_t * desc, int argc, char* argv[], JSList ** param_ptr);
00057 static void silent_jack_error_callback (const char *desc)
00058 {}
00059
00060 static void copyright(FILE* file)
00061 {
00062 fprintf (file, "jackdmp " VERSION "\n"
00063 "Copyright 2001-2005 Paul Davis and others.\n"
00064 "Copyright 2004-2008 Grame.\n"
00065 "jackdmp comes with ABSOLUTELY NO WARRANTY\n"
00066 "This is free software, and you are welcome to redistribute it\n"
00067 "under certain conditions; see the file COPYING for details\n");
00068 }
00069
00070 static void usage (FILE *file)
00071 {
00072 copyright (file);
00073 fprintf (file, "\n"
00074 "usage: jackdmp [ --realtime OR -R [ --realtime-priority OR -P priority ] ]\n"
00075 " [ --name OR -n server-name ]\n"
00076
00077
00078 " [ --timeout OR -t client-timeout-in-msecs ]\n"
00079 " [ --loopback OR -L loopback-port-number ]\n"
00080
00081 " [ --verbose OR -v ]\n"
00082 " [ --replace-registry OR -r ]\n"
00083 " [ --silent OR -s ]\n"
00084 " [ --sync OR -S ]\n"
00085 " [ --version OR -V ]\n"
00086 " -d driver [ ... driver args ... ]\n"
00087 " where driver can be `alsa', `coreaudio', 'portaudio' or `dummy'\n"
00088 " jackdmp -d driver --help\n"
00089 " to display options for each driver\n\n");
00090 }
00091
00092 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, const char* server_name)
00093 {
00094 printf("Jackdmp: sync = %ld timeout = %ld rt = %ld priority = %ld verbose = %ld \n", sync, time_out_ms, rt, priority, verbose);
00095 fServer = new JackServer(sync, temporary, time_out_ms, rt, priority, loopback, verbose, server_name);
00096 int res = fServer->Open(driver_desc, driver_params);
00097 return (res < 0) ? res : fServer->Start();
00098 }
00099
00100 static int JackStop()
00101 {
00102 fServer->Stop();
00103 fServer->Close();
00104 printf("Jackdmp: server close\n");
00105 delete fServer;
00106 printf("Jackdmp: delete server\n");
00107 return 0;
00108 }
00109
00110 static int JackDelete()
00111 {
00112 delete fServer;
00113 printf("Jackdmp: delete server\n");
00114 return 0;
00115 }
00116
00117 static void intrpt(int signum)
00118 {
00119 printf("jack main caught signal %d\n", signum);
00120 (void) signal(SIGINT, SIG_DFL);
00121 SetEvent(waitEvent);
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 int main(int argc, char* argv[])
00253 {
00254 jack_driver_desc_t * driver_desc;
00255 const char *options = "-ad:P:uvshVRL:STFl:t:mn:p:";
00256 struct option long_options[] = {
00257 { "driver", 1, 0, 'd'
00258 },
00259 { "verbose", 0, 0, 'v' },
00260 { "help", 0, 0, 'h' },
00261 { "port-max", 1, 0, 'p' },
00262 { "no-mlock", 0, 0, 'm' },
00263 { "name", 0, 0, 'n' },
00264 { "unlock", 0, 0, 'u' },
00265 { "realtime", 0, 0, 'R' },
00266 { "replace-registry", 0, 0, 'r' },
00267 { "loopback", 0, 0, 'L' },
00268 { "realtime-priority", 1, 0, 'P' },
00269 { "timeout", 1, 0, 't' },
00270 { "temporary", 0, 0, 'T' },
00271 { "version", 0, 0, 'V' },
00272 { "silent", 0, 0, 's' },
00273 { "sync", 0, 0, 'S' },
00274 { 0, 0, 0, 0 }
00275 };
00276 int opt = 0;
00277 int option_index = 0;
00278 int seen_driver = 0;
00279 char *driver_name = NULL;
00280 char **driver_args = NULL;
00281 JSList * driver_params;
00282 int driver_nargs = 1;
00283 int show_version = 0;
00284 int replace_registry = 0;
00285 int sync = 0;
00286 int i;
00287 int rc;
00288 char c;
00289
00290
00291 if ((waitEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL) {
00292 printf("CreateEvent fails err = %ld\n", GetLastError());
00293 return 0;
00294 }
00295
00296 opterr = 0;
00297 while (!seen_driver &&
00298 (opt = getopt_long(argc, argv, options,
00299 long_options, &option_index)) != EOF) {
00300 switch (opt) {
00301
00302 case 'd':
00303 seen_driver = 1;
00304 driver_name = optarg;
00305 break;
00306
00307 case 'v':
00308 xverbose = 1;
00309 break;
00310
00311 case 's':
00312
00313
00314 break;
00315
00316 case 'S':
00317 sync = 1;
00318 break;
00319
00320 case 'n':
00321 server_name = optarg;
00322 break;
00323
00324 case 'm':
00325 do_mlock = 0;
00326 break;
00327
00328 case 'p':
00329 port_max = (unsigned int)atol(optarg);
00330 break;
00331
00332 case 'P':
00333 realtime_priority = atoi(optarg);
00334 break;
00335
00336 case 'r':
00337 replace_registry = 1;
00338 break;
00339
00340 case 'R':
00341 realtime = 1;
00342 break;
00343
00344 case 'L':
00345 loopback = atoi(optarg);
00346 break;
00347
00348 case 'T':
00349 temporary = 1;
00350 break;
00351
00352 case 't':
00353 client_timeout = atoi(optarg);
00354 break;
00355
00356 case 'u':
00357 do_unlock = 1;
00358 break;
00359
00360 case 'V':
00361 show_version = 1;
00362 break;
00363
00364 default:
00365 fprintf(stderr, "unknown option character %c\n",
00366 optopt);
00367
00368 case 'h':
00369 usage(stdout);
00370 return -1;
00371 }
00372 }
00373
00374 if (!seen_driver) {
00375 usage (stderr);
00376
00377 return 0;
00378 }
00379
00380 drivers = jack_drivers_load (drivers);
00381 if (!drivers) {
00382 fprintf (stderr, "jackdmp: no drivers found; exiting\n");
00383
00384 return 0;
00385 }
00386
00387 driver_desc = jack_find_driver_descriptor (drivers, driver_name);
00388 if (!driver_desc) {
00389 fprintf (stderr, "jackdmp: unknown driver '%s'\n", driver_name);
00390
00391 return 0;
00392 }
00393
00394 if (optind < argc) {
00395 driver_nargs = 1 + argc - optind;
00396 } else {
00397 driver_nargs = 1;
00398 }
00399
00400 if (driver_nargs == 0) {
00401 fprintf (stderr, "No driver specified ... hmm. JACK won't do"
00402 " anything when run like this.\n");
00403 return -1;
00404 }
00405
00406 driver_args = (char **) malloc (sizeof (char *) * driver_nargs);
00407 driver_args[0] = driver_name;
00408
00409 for (i = 1; i < driver_nargs; i++) {
00410 driver_args[i] = argv[optind++];
00411 }
00412
00413 if (jack_parse_driver_params (driver_desc, driver_nargs,
00414 driver_args, &driver_params)) {
00415
00416 return 0;
00417 }
00418
00419
00420
00421
00422 copyright (stdout);
00423
00424 rc = jack_register_server (server_name, replace_registry);
00425 switch (rc) {
00426 case EEXIST:
00427 fprintf (stderr, "`%s' server already active\n", server_name);
00428
00429 return 0;
00430 case ENOSPC:
00431 fprintf (stderr, "too many servers already active\n");
00432
00433 return 0;
00434 case ENOMEM:
00435 fprintf (stderr, "no access to shm registry\n");
00436
00437 return 0;
00438 default:
00439 if (xverbose)
00440 fprintf (stderr, "server `%s' registered\n",
00441 server_name);
00442 }
00443
00444
00445
00446
00447 jack_cleanup_shm();
00448
00449
00450 if (!realtime && client_timeout == 0)
00451 client_timeout = 500;
00452
00453 int res = JackStart(driver_desc, driver_params, sync, client_timeout, realtime, realtime_priority, loopback, xverbose, server_name);
00454 if (res < 0) {
00455 printf("Cannot start server... exit\n");
00456 JackDelete();
00457 return 0;
00458 }
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470 (void) signal(SIGINT, intrpt);
00471 (void) signal(SIGABRT, intrpt);
00472 (void) signal(SIGTERM, intrpt);
00473
00474 if ((res = WaitForSingleObject(waitEvent, INFINITE)) != WAIT_OBJECT_0) {
00475 printf("WaitForSingleObject fails err = %ld\n", GetLastError());
00476 }
00477
00478
00479
00480
00481
00482
00483
00484 JackStop();
00485
00486 jack_cleanup_shm();
00487
00488 jack_unregister_server(server_name);
00489
00490 CloseHandle(waitEvent);
00491 return 1;
00492 }
00493
00494