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-2006 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 " [ --silent OR -s ]\n"
00083 " [ --sync OR -S ]\n"
00084 " [ --version OR -V ]\n"
00085 " -d driver [ ... driver args ... ]\n"
00086 " where driver can be `alsa', `coreaudio', 'portaudio' or `dummy'\n"
00087 " jackdmp -d driver --help\n"
00088 " to display options for each driver\n\n");
00089 }
00090
00091 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)
00092 {
00093 printf("Jackdmp: sync = %ld timeout = %ld rt = %ld priority = %ld verbose = %ld \n", sync, time_out_ms, rt, priority, verbose);
00094 fServer = new JackServer(sync, time_out_ms, rt, priority, loopback, verbose);
00095 int res = fServer->Open(driver_desc, driver_params);
00096 return (res < 0) ? res : fServer->Start();
00097 }
00098
00099 static int JackStop()
00100 {
00101 fServer->Stop();
00102 fServer->Close();
00103 printf("Jackdmp: server close\n");
00104 delete fServer;
00105 printf("Jackdmp: delete server\n");
00106 return 0;
00107 }
00108
00109 static int JackDelete()
00110 {
00111 delete fServer;
00112 printf("Jackdmp: delete server\n");
00113 return 0;
00114 }
00115
00116 static void intrpt(int signum)
00117 {
00118 printf("jack main caught signal %d\n", signum);
00119 (void) signal(SIGINT, SIG_DFL);
00120 SetEvent(waitEvent);
00121 }
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 int main(int argc, char* argv[])
00252 {
00253 jack_driver_desc_t * driver_desc;
00254 const char *options = "-ad:P:uvshVRL:STFl:t:mn:p:";
00255 struct option long_options[] = {
00256 { "driver", 1, 0, 'd'
00257 },
00258 { "verbose", 0, 0, 'v' },
00259 { "help", 0, 0, 'h' },
00260 { "port-max", 1, 0, 'p' },
00261 { "no-mlock", 0, 0, 'm' },
00262 { "name", 0, 0, 'n' },
00263 { "unlock", 0, 0, 'u' },
00264 { "realtime", 0, 0, 'R' },
00265 { "loopback", 0, 0, 'L' },
00266 { "realtime-priority", 1, 0, 'P' },
00267 { "timeout", 1, 0, 't' },
00268 { "temporary", 0, 0, 'T' },
00269 { "version", 0, 0, 'V' },
00270 { "silent", 0, 0, 's' },
00271 { "sync", 0, 0, 'S' },
00272 { 0, 0, 0, 0 }
00273 };
00274 int opt = 0;
00275 int option_index = 0;
00276 int seen_driver = 0;
00277 char *driver_name = NULL;
00278 char **driver_args = NULL;
00279 JSList * driver_params;
00280 int driver_nargs = 1;
00281 int show_version = 0;
00282 int sync = 0;
00283 int i;
00284 int rc;
00285 char c;
00286
00287
00288 if ((waitEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL) {
00289 printf("CreateEvent fails err = %ld\n", GetLastError());
00290 return 0;
00291 }
00292
00293 opterr = 0;
00294 while (!seen_driver &&
00295 (opt = getopt_long(argc, argv, options,
00296 long_options, &option_index)) != EOF) {
00297 switch (opt) {
00298
00299 case 'd':
00300 seen_driver = 1;
00301 driver_name = optarg;
00302 break;
00303
00304 case 'v':
00305 xverbose = 1;
00306 break;
00307
00308 case 's':
00309
00310
00311 break;
00312
00313 case 'S':
00314 sync = 1;
00315 break;
00316
00317 case 'n':
00318 server_name = optarg;
00319 break;
00320
00321 case 'm':
00322 do_mlock = 0;
00323 break;
00324
00325 case 'p':
00326 port_max = (unsigned int)atol(optarg);
00327 break;
00328
00329 case 'P':
00330 realtime_priority = atoi(optarg);
00331 break;
00332
00333 case 'R':
00334 realtime = 1;
00335 break;
00336
00337 case 'L':
00338 loopback = atoi(optarg);
00339 break;
00340
00341 case 'T':
00342 temporary = 1;
00343 break;
00344
00345 case 't':
00346 client_timeout = atoi(optarg);
00347 break;
00348
00349 case 'u':
00350 do_unlock = 1;
00351 break;
00352
00353 case 'V':
00354 show_version = 1;
00355 break;
00356
00357 default:
00358 fprintf(stderr, "unknown option character %c\n",
00359 optopt);
00360
00361 case 'h':
00362 usage(stdout);
00363 return -1;
00364 }
00365 }
00366
00367 if (!seen_driver) {
00368 usage (stderr);
00369
00370 return 0;
00371 }
00372
00373 drivers = jack_drivers_load (drivers);
00374 if (!drivers) {
00375 fprintf (stderr, "jackdmp: no drivers found; exiting\n");
00376
00377 return 0;
00378 }
00379
00380 driver_desc = jack_find_driver_descriptor (drivers, driver_name);
00381 if (!driver_desc) {
00382 fprintf (stderr, "jackdmp: unknown driver '%s'\n", driver_name);
00383
00384 return 0;
00385 }
00386
00387 if (optind < argc) {
00388 driver_nargs = 1 + argc - optind;
00389 } else {
00390 driver_nargs = 1;
00391 }
00392
00393 if (driver_nargs == 0) {
00394 fprintf (stderr, "No driver specified ... hmm. JACK won't do"
00395 " anything when run like this.\n");
00396 return -1;
00397 }
00398
00399 driver_args = (char **) malloc (sizeof (char *) * driver_nargs);
00400 driver_args[0] = driver_name;
00401
00402 for (i = 1; i < driver_nargs; i++) {
00403 driver_args[i] = argv[optind++];
00404 }
00405
00406 if (jack_parse_driver_params (driver_desc, driver_nargs,
00407 driver_args, &driver_params)) {
00408
00409 return 0;
00410 }
00411
00412
00413
00414
00415 copyright (stdout);
00416
00417 rc = jack_register_server (server_name);
00418 switch (rc) {
00419 case EEXIST:
00420 fprintf (stderr, "`%s' server already active\n", server_name);
00421
00422 return 0;
00423 case ENOSPC:
00424 fprintf (stderr, "too many servers already active\n");
00425
00426 return 0;
00427 case ENOMEM:
00428 fprintf (stderr, "no access to shm registry\n");
00429
00430 return 0;
00431 default:
00432 if (xverbose)
00433 fprintf (stderr, "server `%s' registered\n",
00434 server_name);
00435 }
00436
00437
00438
00439
00440 jack_cleanup_shm();
00441
00442
00443 if (!realtime && client_timeout == 0)
00444 client_timeout = 500;
00445
00446 int res = JackStart(driver_desc, driver_params, sync, client_timeout, realtime, realtime_priority, loopback, xverbose);
00447 if (res < 0) {
00448 printf("Cannot start server... exit\n");
00449 JackDelete();
00450 return 0;
00451 }
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463 (void) signal(SIGINT, intrpt);
00464 (void) signal(SIGABRT, intrpt);
00465 (void) signal(SIGTERM, intrpt);
00466
00467 if ((res = WaitForSingleObject(waitEvent, INFINITE)) != WAIT_OBJECT_0) {
00468 printf("WaitForSingleObject fails err = %ld\n", GetLastError());
00469 }
00470
00471
00472
00473
00474
00475
00476
00477 JackStop();
00478
00479 jack_cleanup_shm();
00480
00481 jack_unregister_server(server_name);
00482
00483 CloseHandle(waitEvent);
00484 return 1;
00485 }
00486
00487