~ubuntu-branches/ubuntu/trusty/vorbis-tools/trusty

« back to all changes in this revision

Viewing changes to ogg123/ogg123.c

  • Committer: Bazaar Package Importer
  • Author(s): Jesus Climent
  • Date: 2005-04-10 09:22:24 UTC
  • mfrom: (2.1.1 warty)
  • Revision ID: james.westby@ubuntu.com-20050410092224-xtukpa3qghghhjje
Tags: 1.0.1-1.3
* Authorized NMU.
* Modified alsa to mention alsa09 (although the device might be nowadays
  alsa, back, since alsa1.0 has been already released). (Closes: #258286)
* Modified the manpage/help message for vorbiscomment to make it a bit more
  userfiendly: Closes: #252531.
* Added oggdec to the long description field, so that it triggers apt-cache
  searches: Closes: #274894.
* Typos in manpages: Closes: #302150.
* Escaped dashes in manpage: Closes: #264365.
* Quiet option is actually with -Q, not -q (Closes: #211289) Reported
  upstream but patched for Debian.
* Change input.wav with inputfile, since we accept flac-formated files:
  Closes: #262509.
* Translation bits:
  * Updated translation hu.po: Closes: #272037.
  * French translation correction: Encodage -> Codage (Closes: #248431).
  * debian/rules: remove .gmo's to avoid clash with uploaded tarball.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
 *                                                                  *
15
15
 ********************************************************************
16
16
 
17
 
 last mod: $Id: ogg123.c,v 1.56 2001/12/24 15:58:03 volsung Exp $
 
17
 last mod: $Id: ogg123.c,v 1.71 2003/11/27 19:38:29 volsung Exp $
18
18
 
19
19
 ********************************************************************/
20
20
 
28
28
#include <signal.h>
29
29
#include <unistd.h>
30
30
#include <sys/time.h>
 
31
#include <sys/stat.h>
 
32
#include <unistd.h>
 
33
#include <locale.h>
31
34
 
32
35
#include "audio.h"
33
36
#include "buffer.h"
37
40
#include "format.h"
38
41
#include "transport.h"
39
42
#include "status.h"
 
43
#include "playlist.h"
40
44
#include "compat.h"
41
45
 
42
46
#include "ogg123.h"
 
47
#include "i18n.h"
 
48
 
43
49
 
44
50
void exit_cleanup ();
45
51
void play (char *source_string);
66
72
 
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}
74
80
};
75
81
 
76
82
 
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};
79
85
 
80
86
 
81
87
/* ------------------------------- signal handler ------------------------- */
98
104
    else
99
105
      sig_request.skipfile = 1;
100
106
 
 
107
    sig_request.cancel = 1;
101
108
    sig_request.last_ctrl_c = now;
102
109
    break;
103
110
 
 
111
  case SIGTERM:
 
112
    sig_request.exit = 1;
 
113
    break;
 
114
 
104
115
  case SIGTSTP:
105
116
    sig_request.pause = 1;
106
117
    /* buffer_Pause (Options.outputOpts.buffer);
133
144
  opts->nth = 1;
134
145
  opts->ntimes = 1;
135
146
  opts->seekpos = 0.0;
 
147
  opts->endpos = -1.0; /* Mark as unset */
136
148
  opts->buffer_size = 128 * 1024;
137
149
  opts->prebuffer = 0.0f;
138
150
  opts->input_buffer_size = 64 * 1024;
140
152
  opts->default_device = NULL;
141
153
 
142
154
  opts->status_freq = 10.0;
 
155
  opts->playlist = NULL;
 
156
 
143
157
}
144
158
 
145
159
 
171
185
    stats[7].enabled = 0;
172
186
  }
173
187
    
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 */
175
192
}
176
193
 
177
194
 
241
258
    print_statistics_action(NULL, pstats_arg);
242
259
}
243
260
 
 
261
double current_time (decoder_t *decoder)
 
262
{
 
263
  decoder_stats_t *stats;
 
264
  double ret;
 
265
 
 
266
  stats = decoder->format->statistics(decoder);
 
267
  ret = stats->current_time;
 
268
 
 
269
  free(stats);
 
270
 
 
271
  return ret;
 
272
}
244
273
 
245
274
void print_audio_devices_info(audio_device_t *d)
246
275
{
249
278
  while (d != NULL) {
250
279
    info = ao_driver_info(d->driver_id);
251
280
    
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, "");
255
285
 
256
286
    d = d->next_device;
257
287
  }
266
296
int main(int argc, char **argv)
267
297
{
268
298
  int optind;
 
299
  char **playlist_array;
 
300
  int items;
 
301
  struct stat stat_buf;
 
302
  int i;
 
303
 
 
304
  setlocale(LC_ALL, "");
 
305
  bindtextdomain(PACKAGE, LOCALEDIR);
 
306
  textdomain(PACKAGE);
269
307
 
270
308
  ao_initialize();
271
309
  stat_format = stat_format_create();
273
311
  file_options_init(file_opts);
274
312
 
275
313
  parse_std_configs(file_opts);
 
314
  options.playlist = playlist_create();
276
315
  optind = parse_cmdline_options(argc, argv, &options, file_opts);
277
316
 
278
317
  audio_play_arg.devices = options.devices;
279
318
  audio_play_arg.stat_format = stat_format;
280
319
 
 
320
  /* Add remaining arguments to playlist */
 
321
  for (i = optind; i < argc; i++) {
 
322
    if (stat(argv[i], &stat_buf) == 0) {
 
323
 
 
324
      if (S_ISDIR(stat_buf.st_mode)) {
 
325
        if (playlist_append_directory(options.playlist, argv[i]) == 0)
 
326
          fprintf(stderr, 
 
327
                  _("Warning: Could not read directory %s.\n"), argv[i]);
 
328
      } else {
 
329
        playlist_append_file(options.playlist, argv[i]);
 
330
      }
 
331
    } else /* If we can't stat it, it might be a non-disk source */
 
332
      playlist_append_file(options.playlist, argv[i]);
 
333
 
 
334
 
 
335
  }
 
336
 
 
337
 
 
338
  /* Do we have anything left to play? */
 
339
  if (playlist_length(options.playlist) == 0) {
 
340
    cmdline_usage();
 
341
    exit(1);
 
342
  } else {
 
343
    playlist_array = playlist_to_array(options.playlist, &items);
 
344
    playlist_destroy(options.playlist);
 
345
    options.playlist = NULL;
 
346
  }
 
347
 
281
348
  /* Don't use status_message until after this point! */
282
349
  status_set_verbosity(options.verbosity);
283
350
 
284
351
  print_audio_devices_info(options.devices);
285
352
 
286
 
  /* Setup signal handlers and callbacks */
287
 
 
288
 
  ATEXIT (exit_cleanup);
289
 
  signal (SIGINT, signal_handler);
290
 
  signal (SIGTSTP, signal_handler);
291
 
  signal (SIGCONT, signal_handler);
292
 
  signal (SIGALRM, signal_handler);
293
 
 
294
 
  /* Do we have anything left to play? */
295
 
  if (optind == argc) {
296
 
    cmdline_usage();
297
 
    exit(1);
298
 
  }
299
353
  
300
354
  /* Setup buffer */ 
301
355
  if (options.buffer_size > 0) {
304
358
                                 audio_play_callback, &audio_play_arg,
305
359
                                 AUDIO_CHUNK_SIZE);
306
360
    if (audio_buffer == NULL) {
307
 
      status_error("Error: Could not create audio buffer.\n");
 
361
      status_error(_("Error: Could not create audio buffer.\n"));
308
362
      exit(1);
309
363
    }
310
364
  } else
317
371
    
318
372
    srandom(time(NULL));
319
373
    
320
 
    for (i = optind; i < argc; i++) {
321
 
      int j = i + random() % (argc - i);
322
 
      char *temp = argv[i];
323
 
      argv[i] = argv[j];
324
 
      argv[j] = temp;
 
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;
325
379
    }
326
380
  }
327
381
 
 
382
  /* Setup signal handlers and callbacks */
 
383
 
 
384
  ATEXIT (exit_cleanup);
 
385
  signal (SIGINT, signal_handler);
 
386
  signal (SIGTSTP, signal_handler);
 
387
  signal (SIGCONT, signal_handler);
 
388
  signal (SIGTERM, signal_handler);
 
389
 
328
390
  /* Play the files/streams */
329
 
 
330
 
  while (optind < argc && !sig_request.exit) {
331
 
    play(argv[optind]);
332
 
    optind++;
 
391
  i = 0;
 
392
  while (i < items && !sig_request.exit) {
 
393
    play(playlist_array[i]);
 
394
    i++;
333
395
  }
334
396
 
 
397
  playlist_array_destroy(playlist_array, items);
335
398
 
336
399
  exit (0);
337
400
}
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;
361
424
 
 
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;
362
430
 
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;
373
441
  } else {
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;
377
445
  }
378
446
 
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);
382
450
    return;
383
451
  }
384
452
  
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);
387
455
    return;
388
456
  }
389
457
 
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);
393
461
    return;
394
462
  }
395
463
  
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,
401
 
                 format->name);
 
467
 
 
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,
 
472
                   format->name);
402
473
    return;
403
474
  }
404
475
 
405
476
  /* Decide which statistics are valid */
406
477
  select_stats(stat_format, &options, source, decoder, audio_buffer);
407
478
 
408
 
 
409
 
  /* Reset all of the signal flags */
410
 
  sig_request.skipfile = 0;
411
 
  sig_request.exit     = 0;
412
 
  sig_request.pause    = 0;
413
 
 
414
479
  /* Start the audio playback thread before we begin sending data */    
415
480
  if (audio_buffer != NULL) {
416
481
    
421
486
 
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);
425
490
 
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);
 
497
      return;
 
498
    }
430
499
  }
431
500
 
432
501
  /* Main loop:  Iterates over all of the logical bitstreams in the file */
464
533
        eof = eos = 1;
465
534
        break;
466
535
      } else if (ret < 0) {
467
 
        status_error("Error: Decoding failure.\n");
 
536
        status_error(_("Error: Decoding failure.\n"));
468
537
        break;
469
538
      }
470
539
 
495
564
      } else
496
565
        next_status -= ret;
497
566
 
 
567
      if (options.endpos > 0.0 && options.endpos <= current_time(decoder)) {
 
568
        eof = eos = 1;
 
569
        break;
 
570
      }
 
571
 
498
572
 
499
573
      /* Write audio data block to output, skipping or repeating chunks
500
574
         as needed */
509
583
          nthc = options.nth - 1;
510
584
        }
511
585
        
512
 
      } while (++ntimesc < options.ntimes);
 
586
      } while (!sig_request.exit && !sig_request.skipfile &&
 
587
               ++ntimesc < options.ntimes);
513
588
 
514
589
      ntimesc = 0;
515
590
            
537
612
  transport->close(source);
538
613
  status_reset_output_lock();  /* In case we were killed mid-output */
539
614
 
540
 
  status_message(1, "Done.");
 
615
  status_message(1, _("Done."));
541
616
  
542
617
  if (sig_request.exit)
543
618
    exit (0);