67
73
file_option_t file_opts[] = {
68
74
/* found, name, description, type, ptr, default */
69
{0, "default_device", "default output device", opt_type_string,
75
{0, "default_device", N_("default output device"), opt_type_string,
70
76
&options.default_device, NULL},
71
{0, "shuffle", "shuffle playlist", opt_type_bool,
77
{0, "shuffle", N_("shuffle playlist"), opt_type_bool,
72
78
&options.shuffle, &int_0},
73
79
{0, NULL, NULL, 0, NULL, NULL}
77
83
/* Flags set by the signal handler to control the threads */
78
signal_request_t sig_request = {0, 0, 0, 0};
84
signal_request_t sig_request = {0, 0, 0, 0, 0};
81
87
/* ------------------------------- signal handler ------------------------- */
171
185
stats[7].enabled = 0;
174
/* Put logic here to decide if this stream needs a total time display */
188
/* Assume we need total time display, and let display_statistics()
189
determine at what point it should be turned off during playback */
190
stats[2].enabled = 1; /* Remaining playback time */
191
stats[3].enabled = 1; /* Total playback time */
241
258
print_statistics_action(NULL, pstats_arg);
261
double current_time (decoder_t *decoder)
263
decoder_stats_t *stats;
266
stats = decoder->format->statistics(decoder);
267
ret = stats->current_time;
245
274
void print_audio_devices_info(audio_device_t *d)
249
278
while (d != NULL) {
250
279
info = ao_driver_info(d->driver_id);
252
status_message(2, "\nDevice: %s", info->name);
253
status_message(2, "Author: %s", info->author);
254
status_message(2, "Comments: %s\n", info->comment);
281
status_message(2, _("\nAudio Device: %s"), info->name);
282
status_message(3, _("Author: %s"), info->author);
283
status_message(3, _("Comments: %s"), info->comment);
284
status_message(2, "");
256
286
d = d->next_device;
273
311
file_options_init(file_opts);
275
313
parse_std_configs(file_opts);
314
options.playlist = playlist_create();
276
315
optind = parse_cmdline_options(argc, argv, &options, file_opts);
278
317
audio_play_arg.devices = options.devices;
279
318
audio_play_arg.stat_format = stat_format;
320
/* Add remaining arguments to playlist */
321
for (i = optind; i < argc; i++) {
322
if (stat(argv[i], &stat_buf) == 0) {
324
if (S_ISDIR(stat_buf.st_mode)) {
325
if (playlist_append_directory(options.playlist, argv[i]) == 0)
327
_("Warning: Could not read directory %s.\n"), argv[i]);
329
playlist_append_file(options.playlist, argv[i]);
331
} else /* If we can't stat it, it might be a non-disk source */
332
playlist_append_file(options.playlist, argv[i]);
338
/* Do we have anything left to play? */
339
if (playlist_length(options.playlist) == 0) {
343
playlist_array = playlist_to_array(options.playlist, &items);
344
playlist_destroy(options.playlist);
345
options.playlist = NULL;
281
348
/* Don't use status_message until after this point! */
282
349
status_set_verbosity(options.verbosity);
284
351
print_audio_devices_info(options.devices);
286
/* Setup signal handlers and callbacks */
288
ATEXIT (exit_cleanup);
289
signal (SIGINT, signal_handler);
290
signal (SIGTSTP, signal_handler);
291
signal (SIGCONT, signal_handler);
292
signal (SIGALRM, signal_handler);
294
/* Do we have anything left to play? */
295
if (optind == argc) {
300
354
/* Setup buffer */
301
355
if (options.buffer_size > 0) {
318
372
srandom(time(NULL));
320
for (i = optind; i < argc; i++) {
321
int j = i + random() % (argc - i);
322
char *temp = argv[i];
374
for (i = 0; i < items; i++) {
375
int j = i + random() % (items - i);
376
char *temp = playlist_array[i];
377
playlist_array[i] = playlist_array[j];
378
playlist_array[j] = temp;
382
/* Setup signal handlers and callbacks */
384
ATEXIT (exit_cleanup);
385
signal (SIGINT, signal_handler);
386
signal (SIGTSTP, signal_handler);
387
signal (SIGCONT, signal_handler);
388
signal (SIGTERM, signal_handler);
328
390
/* Play the files/streams */
330
while (optind < argc && !sig_request.exit) {
392
while (i < items && !sig_request.exit) {
393
play(playlist_array[i]);
397
playlist_array_destroy(playlist_array, items);
357
420
int eof = 0, eos = 0, ret;
358
421
int nthc = 0, ntimesc = 0;
359
422
int next_status = 0;
360
int status_interval = 0;
423
static int status_interval = 0;
425
/* Reset all of the signal flags */
426
sig_request.cancel = 0;
427
sig_request.skipfile = 0;
428
sig_request.exit = 0;
429
sig_request.pause = 0;
363
431
/* Set preferred audio format (used by decoder) */
364
432
new_audio_fmt.big_endian = ao_is_big_endian();
368
436
/* Select appropriate callbacks */
369
437
if (audio_buffer != NULL) {
370
438
decoder_callbacks.printf_error = &decoder_buffered_error_callback;
371
decoder_callbacks.printf_metadata = &decoder_buffered_error_callback;
439
decoder_callbacks.printf_metadata = &decoder_buffered_metadata_callback;
372
440
decoder_callbacks_arg = audio_buffer;
374
442
decoder_callbacks.printf_error = &decoder_error_callback;
375
decoder_callbacks.printf_metadata = &decoder_error_callback;
443
decoder_callbacks.printf_metadata = &decoder_metadata_callback;
376
444
decoder_callbacks_arg = NULL;
379
447
/* Locate and use transport for this data source */
380
448
if ( (transport = select_transport(source_string)) == NULL ) {
381
status_error("No module could be found to read from %s.\n", source_string);
449
status_error(_("No module could be found to read from %s.\n"), source_string);
385
453
if ( (source = transport->open(source_string, &options)) == NULL ) {
386
status_error("Cannot open %s.\n", source_string);
454
status_error(_("Cannot open %s.\n"), source_string);
390
458
/* Detect the file format and initialize a decoder */
391
459
if ( (format = select_format(source)) == NULL ) {
392
status_error("The file format of %s is not supported.\n", source_string);
460
status_error(_("The file format of %s is not supported.\n"), source_string);
396
464
if ( (decoder = format->init(source, &options, &new_audio_fmt,
397
465
&decoder_callbacks,
398
466
decoder_callbacks_arg)) == NULL ) {
399
status_error("Error opening %s using the %s module."
400
" The file may be corrupted.\n", source_string,
468
/* We may have failed because of user command */
469
if (!sig_request.cancel)
470
status_error(_("Error opening %s using the %s module."
471
" The file may be corrupted.\n"), source_string,
405
476
/* Decide which statistics are valid */
406
477
select_stats(stat_format, &options, source, decoder, audio_buffer);
409
/* Reset all of the signal flags */
410
sig_request.skipfile = 0;
411
sig_request.exit = 0;
412
sig_request.pause = 0;
414
479
/* Start the audio playback thread before we begin sending data */
415
480
if (audio_buffer != NULL) {
422
487
/* Show which file we are playing */
423
488
decoder_callbacks.printf_metadata(decoder_callbacks_arg, 1,
424
"Playing: %s", source_string);
489
_("Playing: %s"), source_string);
426
491
/* Skip over audio */
427
492
if (options.seekpos > 0.0) {
428
if (!format->seek(decoder, options.seekpos, DECODER_SEEK_START))
429
status_error("Could not skip %f seconds of audio.", options.seekpos);
493
if (!format->seek(decoder, options.seekpos, DECODER_SEEK_START)) {
494
status_error(_("Could not skip %f seconds of audio."), options.seekpos);
495
if (audio_buffer != NULL)
496
buffer_thread_kill(audio_buffer);
432
501
/* Main loop: Iterates over all of the logical bitstreams in the file */