2
mpg123: main code of the program (not of the decoder...)
4
copyright 1995-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
5
see COPYING and AUTHORS files in distribution or http://mpg123.de
6
initially written by Michael Hipp
14
#include <sys/types.h>
15
#if !defined(WIN32) && !defined(GENERIC)
18
#include <sys/resource.h>
40
static void usage(int err);
41
static void want_usage(char* arg);
42
static void long_usage(int err);
43
static void want_long_usage(char* arg);
44
static void print_title(FILE* o);
45
static void give_version(char* arg);
47
struct parameter param = {
48
FALSE , /* aggressiv */
51
FALSE , /* remote to stderr */
52
DECODE_AUDIO , /* write samples to audio device */
53
FALSE , /* silent operation */
54
FALSE , /* xterm title on/off */
55
0 , /* second level buffer size */
56
TRUE , /* resync after stream error */
57
0 , /* verbose level */
59
FALSE , /* term control */
62
0 , /* force stereo */
66
FALSE , /* checkrange */
69
0 , /* force_reopen, always (re)opens audio device for next song */
71
0 , /* autodetect from CPUFLAGS */
72
FALSE , /* normal operation */
74
FALSE, /* try to run process in 'realtime mode' */
75
{ 0,}, /* wav,cdr,au Filename */
77
0, /* gapless off per default - yet */
79
0, /* default is to play all titles in playlist */
80
-1, /* do not use rva per default */
81
NULL /* no playlist per default */
85
char *equalfile = NULL;
86
/* ThOr: pointers are not TRUE or FALSE */
87
int have_eq_settings = FALSE;
88
long outscale = MAXOUTBURST;
94
static int intflag = FALSE;
98
#if !defined(WIN32) && !defined(GENERIC)
99
static void catch_child(void)
101
while (waitpid(-1, NULL, WNOHANG) > 0);
104
static void catch_interrupt(void)
110
/* oh, what a mess... */
111
void next_track(void)
116
static struct frame fr;
117
struct audio_info_struct ai,pre_ai;
118
txfermem *buffermem = NULL;
119
#define FRAMEBUFUNIT (18 * 64 * 4)
121
void set_synth_functions(struct frame *fr);
123
void init_output(void)
125
static int init_done = FALSE;
132
* Only DECODE_AUDIO and DECODE_FILE are sanely handled by the
133
* buffer process. For now, we just ignore the request
134
* to buffer the output. [dk]
136
if (param.usebuffer && (param.outmode != DECODE_AUDIO) &&
137
(param.outmode != DECODE_FILE)) {
138
fprintf(stderr, "Sorry, won't buffer output unless writing plain audio.\n");
142
if (param.usebuffer) {
143
unsigned int bufferbytes;
144
sigset_t newsigset, oldsigset;
145
if (param.usebuffer < 32)
146
param.usebuffer = 32; /* minimum is 32 Kbytes! */
147
bufferbytes = (param.usebuffer * 1024);
148
bufferbytes -= bufferbytes % FRAMEBUFUNIT;
149
/* +1024 for NtoM rounding problems */
150
xfermem_init (&buffermem, bufferbytes ,0,1024);
151
pcm_sample = (unsigned char *) buffermem->data;
153
sigemptyset (&newsigset);
154
sigaddset (&newsigset, SIGUSR1);
155
sigprocmask (SIG_BLOCK, &newsigset, &oldsigset);
156
catchsignal (SIGCHLD, catch_child);
157
switch ((buffer_pid = fork())) {
167
rd->close(rd); /* child doesn't need the input stream */
168
xfermem_init_reader (buffermem);
169
buffer_loop (&ai, &oldsigset);
170
xfermem_done_reader (buffermem);
171
xfermem_done (buffermem);
173
default: /* parent */
174
xfermem_init_writer (buffermem);
175
param.outmode = DECODE_BUFFER;
180
/* + 1024 for NtoM rate converter */
181
if (!(pcm_sample = (unsigned char *) malloc(audiobufsize * 2 + 1024))) {
193
switch(param.outmode) {
195
if(audio_open(&ai) < 0) {
205
wav_open(&ai,param.filename);
208
au_open(&ai,param.filename);
211
cdr_open(&ai,param.filename);
216
static void set_output_h(char *a)
219
ai.output = AUDIO_OUT_HEADPHONES;
221
ai.output |= AUDIO_OUT_HEADPHONES;
223
static void set_output_s(char *a)
226
ai.output = AUDIO_OUT_INTERNAL_SPEAKER;
228
ai.output |= AUDIO_OUT_INTERNAL_SPEAKER;
230
static void set_output_l(char *a)
233
ai.output = AUDIO_OUT_LINE_OUT;
235
ai.output |= AUDIO_OUT_LINE_OUT;
238
static void set_output (char *arg)
241
case 'h': set_output_h(arg); break;
242
case 's': set_output_s(arg); break;
243
case 'l': set_output_l(arg); break;
245
fprintf (stderr, "%s: Unknown argument \"%s\" to option \"%s\".\n",
246
prgName, arg, loptarg);
251
void set_verbose (char *arg)
255
void set_wav(char *arg)
257
param.outmode = DECODE_WAV;
258
strncpy(param.filename,arg,255);
259
param.filename[255] = 0;
261
void set_cdr(char *arg)
263
param.outmode = DECODE_CDR;
264
strncpy(param.filename,arg,255);
265
param.filename[255] = 0;
267
void set_au(char *arg)
269
param.outmode = DECODE_AU;
270
strncpy(param.filename,arg,255);
271
param.filename[255] = 0;
273
static void SetOutFile(char *Arg)
275
param.outmode=DECODE_FILE;
276
OutputDescriptor=open(Arg,O_WRONLY,0);
277
if(OutputDescriptor==-1) {
278
fprintf(stderr,"Can't open %s for writing (%s).\n",Arg,strerror(errno));
282
static void SetOutStdout(char *Arg)
284
param.outmode=DECODE_FILE;
287
static void SetOutStdout1(char *Arg)
289
param.outmode=DECODE_AUDIOFILE;
293
void realtime_not_compiled(char *arg)
295
fprintf(stderr,"Option '-T / --realtime' not compiled into this binary.\n");
298
/* Please note: GLO_NUM expects point to LONG! */
300
* Yeah, and despite that numerous addresses to int variables were
302
* That's not good on my Alpha machine with int=32bit and long=64bit!
303
* Introduced GLO_INT and GLO_LONG as different bits to make that clear.
304
* GLO_NUM no longer exists.
307
{'k', "skip", GLO_ARG | GLO_LONG, 0, &startFrame, 0},
308
{'a', "audiodevice", GLO_ARG | GLO_CHAR, 0, &ai.device, 0},
309
{'2', "2to1", GLO_INT, 0, ¶m.down_sample, 1},
310
{'4', "4to1", GLO_INT, 0, ¶m.down_sample, 2},
311
{'t', "test", GLO_INT, 0, ¶m.outmode, DECODE_TEST},
312
{'s', "stdout", GLO_INT, SetOutStdout, ¶m.outmode, DECODE_FILE},
313
{'S', "STDOUT", GLO_INT, SetOutStdout1, ¶m.outmode,DECODE_AUDIOFILE},
314
{'O', "outfile", GLO_ARG | GLO_CHAR, SetOutFile, NULL, 0},
315
{'c', "check", GLO_INT, 0, ¶m.checkrange, TRUE},
316
{'v', "verbose", 0, set_verbose, 0, 0},
317
{'q', "quiet", GLO_INT, 0, ¶m.quiet, TRUE},
318
{'y', "resync", GLO_INT, 0, ¶m.tryresync, FALSE},
319
{'0', "single0", GLO_INT, 0, ¶m.force_mono, 0},
320
{0, "left", GLO_INT, 0, ¶m.force_mono, 0},
321
{'1', "single1", GLO_INT, 0, ¶m.force_mono, 1},
322
{0, "right", GLO_INT, 0, ¶m.force_mono, 1},
323
{'m', "singlemix", GLO_INT, 0, ¶m.force_mono, 3},
324
{0, "mix", GLO_INT, 0, ¶m.force_mono, 3},
325
{0, "mono", GLO_INT, 0, ¶m.force_mono, 3},
326
{0, "stereo", GLO_INT, 0, ¶m.force_stereo, 1},
327
{0, "reopen", GLO_INT, 0, ¶m.force_reopen, 1},
328
{'g', "gain", GLO_ARG | GLO_LONG, 0, &ai.gain, 0},
329
{'r', "rate", GLO_ARG | GLO_LONG, 0, ¶m.force_rate, 0},
330
{0, "8bit", GLO_INT, 0, ¶m.force_8bit, 1},
331
{0, "headphones", 0, set_output_h, 0,0},
332
{0, "speaker", 0, set_output_s, 0,0},
333
{0, "lineout", 0, set_output_l, 0,0},
334
{'o', "output", GLO_ARG | GLO_CHAR, set_output, 0, 0},
335
{'f', "scale", GLO_ARG | GLO_LONG, 0, &outscale, 0},
336
{'n', "frames", GLO_ARG | GLO_LONG, 0, &numframes, 0},
338
{'C', "control", GLO_INT, 0, ¶m.term_ctrl, TRUE},
340
{'b', "buffer", GLO_ARG | GLO_LONG, 0, ¶m.usebuffer, 0},
341
{'R', "remote", GLO_INT, 0, ¶m.remote, TRUE},
342
{0, "remote-err", GLO_INT, 0, ¶m.remote_err, TRUE},
343
{'d', "doublespeed", GLO_ARG | GLO_LONG, 0, ¶m.doublespeed,0},
344
{'h', "halfspeed", GLO_ARG | GLO_LONG, 0, ¶m.halfspeed, 0},
345
{'p', "proxy", GLO_ARG | GLO_CHAR, 0, &proxyurl, 0},
346
{'@', "list", GLO_ARG | GLO_CHAR, 0, ¶m.listname, 0},
347
/* 'z' comes from the the german word 'zufall' (eng: random) */
348
{'z', "shuffle", GLO_INT, 0, ¶m.shuffle, 1},
349
{'Z', "random", GLO_INT, 0, ¶m.shuffle, 2},
350
{'E', "equalizer", GLO_ARG | GLO_CHAR, 0, &equalfile,1},
351
#ifdef HAVE_SETPRIORITY
352
{0, "aggressive", GLO_INT, 0, ¶m.aggressive, 2},
355
{0, "force-3dnow", GLO_INT, 0, ¶m.stat_3dnow, 1},
356
{0, "no-3dnow", GLO_INT, 0, ¶m.stat_3dnow, 2},
357
{0, "test-3dnow", GLO_INT, 0, ¶m.test_3dnow, TRUE},
359
#if !defined(WIN32) && !defined(GENERIC)
360
{'u', "auth", GLO_ARG | GLO_CHAR, 0, &httpauth, 0},
362
#ifdef HAVE_SCHED_SETSCHEDULER
363
/* check why this should be a long variable instead of int! */
364
{'T', "realtime", GLO_LONG, 0, ¶m.realtime, TRUE },
366
{'T', "realtime", 0, realtime_not_compiled, 0, 0 },
368
{0, "title", GLO_INT, 0, ¶m.xterm_title, TRUE },
369
{'w', "wav", GLO_ARG | GLO_CHAR, set_wav, 0 , 0 },
370
{0, "cdr", GLO_ARG | GLO_CHAR, set_cdr, 0 , 0 },
371
{0, "au", GLO_ARG | GLO_CHAR, set_au, 0 , 0 },
373
{0, "gapless", GLO_INT, 0, ¶m.gapless, 1},
375
{'?', "help", 0, want_usage, 0, 0 },
376
{0 , "longhelp" , 0, want_long_usage, 0, 0 },
377
{0 , "version" , 0, give_version, 0, 0 },
378
{'l', "listentry", GLO_ARG | GLO_LONG, 0, ¶m.listentry, 0 },
379
{0, "rva-mix", GLO_INT, 0, ¶m.rva, 0 },
380
{0, "rva-radio", GLO_INT, 0, ¶m.rva, 0 },
381
{0, "rva-album", GLO_INT, 0, ¶m.rva, 1 },
382
{0, "rva-audiophile", GLO_INT, 0, ¶m.rva, 1 },
387
* Change the playback sample rate.
388
* Consider that changing it after starting playback is not covered by gapless code!
390
static void reset_audio(void)
393
if (param.usebuffer) {
394
/* wait until the buffer is empty,
395
* then tell the buffer process to
396
* change the sample rate. [OF]
398
while (xfermem_get_usedspace(buffermem) > 0)
399
if (xfermem_block(XF_WRITER, buffermem) == XF_CMD_TERMINATE) {
403
buffermem->freeindex = -1;
404
buffermem->readindex = 0; /* I know what I'm doing! ;-) */
405
buffermem->freeindex = 0;
408
buffermem->buf[0] = ai.rate;
409
buffermem->buf[1] = ai.channels;
410
buffermem->buf[2] = ai.format;
415
if (param.outmode == DECODE_AUDIO) {
416
/* audio_reset_parameters(&ai); */
417
/* close and re-open in order to flush
418
* the device's internal buffer before
419
* changing the sample rate. [OF]
422
if (audio_open(&ai) < 0) {
435
precog the audio rate that will be set before output begins
436
this is needed to give gapless code a chance to keep track for firstframe != 0
438
void prepare_audioinfo(struct frame *fr, struct audio_info_struct *nai)
440
long newrate = freqs[fr->sampling_frequency]>>(param.down_sample);
441
fr->down_sample = param.down_sample;
442
audio_fit_capabilities(nai,fr->stereo,newrate);
446
* play a frame read by read_frame();
447
* (re)initialize audio if necessary.
449
* needs a major rewrite .. it's incredible ugly!
451
void play_frame(int init,struct frame *fr)
455
long old_rate,old_format,old_channels;
457
if(fr->header_change || init) {
459
if (!param.quiet && init) {
463
print_header_compact(fr);
466
if(fr->header_change > 1 || init) {
468
old_format = ai.format;
469
old_channels = ai.channels;
471
newrate = freqs[fr->sampling_frequency]>>(param.down_sample);
472
prepare_audioinfo(fr, &ai);
473
if(param.verbose > 1) fprintf(stderr, "Note: audio output rate = %li\n", ai.rate);
475
if(param.gapless && (fr->lay == 3)) layer3_gapless_bytify(fr, &ai);
478
/* check, whether the fitter set our proposed rate */
479
if(ai.rate != newrate) {
480
if(ai.rate == (newrate>>1) )
482
else if(ai.rate == (newrate>>2) )
486
fprintf(stderr,"Warning, flexible rate not heavily tested!\n");
488
if(fr->down_sample > 3)
492
switch(fr->down_sample) {
496
fr->down_sample_sblimit = SBLIMIT>>(fr->down_sample);
500
long n = freqs[fr->sampling_frequency];
503
synth_ntom_set_step(n,m);
506
fr->down_sample_sblimit = SBLIMIT * m;
507
fr->down_sample_sblimit /= n;
510
fr->down_sample_sblimit = SBLIMIT;
517
if(ai.rate != old_rate || ai.channels != old_channels ||
518
ai.format != old_format || param.force_reopen) {
519
if(param.force_mono < 0) {
526
fr->single = param.force_mono;
528
param.force_stereo &= ~0x2;
529
if(fr->single >= 0 && ai.channels == 2) {
530
param.force_stereo |= 0x2;
533
set_synth_functions(fr);
534
init_layer3(fr->down_sample_sblimit);
537
if(fr->down_sample == 3) {
538
long n = freqs[fr->sampling_frequency];
541
fprintf(stderr,"Audio: %2.4f:1 conversion,",(float)n/(float)m);
544
fprintf(stderr,"Audio: 1:%2.4f conversion,",(float)m/(float)n);
548
fprintf(stderr,"Audio: %ld:1 conversion,",(long)pow(2.0,fr->down_sample));
550
fprintf(stderr," rate: %ld, encoding: %s, channels: %d\n",ai.rate,audio_encoding_name(ai.format),ai.channels);
558
if (fr->error_protection) {
559
getbits(16); /* skip crc */
562
/* do the decoding */
563
clip = (fr->do_layer)(fr,param.outmode,&ai);
566
if (param.usebuffer) {
568
buffermem->freeindex =
569
(buffermem->freeindex + pcm_point) % buffermem->size;
570
if (buffermem->wakeme[XF_READER])
571
xfermem_putcmd(buffermem->fd[XF_WRITER], XF_CMD_WAKEUP_INFO);
573
pcm_sample = (unsigned char *) (buffermem->data + buffermem->freeindex);
575
while (xfermem_get_freespace(buffermem) < (FRAMEBUFUNIT << 1))
576
if (xfermem_block(XF_WRITER, buffermem) == XF_CMD_TERMINATE) {
585
if(clip > 0 && param.checkrange)
586
fprintf(stderr,"%d samples clipped\n", clip);
589
void set_synth_functions(struct frame *fr)
591
typedef int (*func)(real *,int,unsigned char *,int *);
592
typedef int (*func_mono)(real *,unsigned char *,int *);
593
typedef void (*func_dct36)(real *,real *,real *,real *,real *);
594
int ds = fr->down_sample;
597
static func funcs[3][4] = {
599
static func funcs[2][4] = {
617
static func_mono funcs_mono[2][2][4] = {
618
{ { synth_1to1_mono2stereo ,
619
synth_2to1_mono2stereo ,
620
synth_4to1_mono2stereo ,
621
synth_ntom_mono2stereo } ,
622
{ synth_1to1_8bit_mono2stereo ,
623
synth_2to1_8bit_mono2stereo ,
624
synth_4to1_8bit_mono2stereo ,
625
synth_ntom_8bit_mono2stereo } } ,
626
{ { synth_1to1_mono ,
630
{ synth_1to1_8bit_mono ,
631
synth_2to1_8bit_mono ,
632
synth_4to1_8bit_mono ,
633
synth_ntom_8bit_mono } }
637
static func_dct36 funcs_dct36[2] = {dct36 , dct36_3dnow};
640
if((ai.format & AUDIO_FORMAT_MASK) == AUDIO_FORMAT_8)
642
fr->synth = funcs[p8][ds];
643
fr->synth_mono = funcs_mono[param.force_stereo?0:1][p8][ds];
645
/* TODO: make autodetection for _all_ x86 optimizations (maybe just for i586+ and keep separate 486 build?) */
647
/* check cpuflags bit 31 (3DNow!) and 23 (MMX) */
648
if((param.stat_3dnow < 2) &&
649
((param.stat_3dnow == 1) ||
650
(getcpuflags() & 0x80800000) == 0x80800000))
652
fr->synth = funcs[2][ds]; /* 3DNow! optimized synth_1to1() */
653
fr->dct36 = funcs_dct36[1]; /* 3DNow! optimized dct36() */
657
fr->dct36 = funcs_dct36[0];
662
make_conv16to8_table(ai.format);
666
int main(int argc, char *argv[])
670
#if !defined(WIN32) && !defined(GENERIC)
671
struct timeval start_time, now;
672
unsigned long secdiff;
681
_wildcard(&argc,&argv);
684
if(sizeof(short) != 2) {
685
fprintf(stderr,"Ouch SHORT has size of %d bytes (required: '2')\n",(int)sizeof(short));
688
if(sizeof(long) < 4) {
689
fprintf(stderr,"Ouch LONG has size of %d bytes (required: at least 4)\n",(int)sizeof(long));
692
(prgName = strrchr(argv[0], '/')) ? prgName++ : (prgName = argv[0]);
694
audio_info_struct_init(&ai);
696
while ((result = getlopt(argc, argv, opts)))
699
fprintf (stderr, "%s: Unknown option \"%s\".\n",
703
fprintf (stderr, "%s: Missing argument for option \"%s\".\n",
708
if (param.test_3dnow) {
709
int cpuflags = getcpuflags();
710
fprintf(stderr,"CPUFLAGS = %08x\n",cpuflags);
711
if ((cpuflags & 0x00800000) == 0x00800000) {
712
fprintf(stderr,"MMX instructions are supported.\n");
714
if ((cpuflags & 0x80000000) == 0x80000000) {
715
fprintf(stderr,"3DNow! instructions are supported.\n");
721
if (loptind >= argc && !param.listname && !param.remote)
724
#if !defined(WIN32) && !defined(GENERIC)
731
if (!(param.listentry < 0) && !param.quiet)
732
print_title(stderr); /* do not pollute stdout! */
734
if(param.force_mono >= 0) {
735
fr.single = param.force_mono;
738
if(param.force_rate && param.down_sample) {
739
fprintf(stderr,"Down sampling and fixed rate options not allowed together!\n");
743
audio_capabilities(&ai);
744
/* equalizer initialization regardless of equalfile */
745
for(j=0; j<32; j++) {
746
equalizer[0][j] = equalizer[1][j] = 1.0;
747
equalizer_sum[0][j] = equalizer_sum[1][j] = 0.0;
749
if(equalfile != NULL) { /* tst; ThOr: not TRUE or FALSE: allocated or not... */
755
fe = fopen(equalfile,"r");
759
float e1,e0; /* %f -> float! */
764
sscanf(line,"%f %f",&e0,&e1);
765
equalizer[0][i] = e0;
766
equalizer[1][i] = e1;
769
have_eq_settings = TRUE;
772
fprintf(stderr,"Can't open equalizer file '%s'\n",equalfile);
775
#ifdef HAVE_SETPRIORITY
776
if(param.aggressive) { /* tst */
777
int mypid = getpid();
778
setpriority(PRIO_PROCESS,mypid,-20);
782
#ifdef HAVE_SCHED_SETSCHEDULER
783
if (param.realtime) { /* Get real-time priority */
784
struct sched_param sp;
785
fprintf(stderr,"Getting real-time priority\n");
786
memset(&sp, 0, sizeof(struct sched_param));
787
sp.sched_priority = sched_get_priority_min(SCHED_FIFO);
788
if (sched_setscheduler(0, SCHED_RR, &sp) == -1)
789
fprintf(stderr,"Can't get real-time priority\n");
793
set_synth_functions(&fr);
795
if(!param.remote) prepare_playlist(argc, argv);
797
make_decode_tables(outscale);
798
init_layer2(); /* inits also shared tables with layer1 */
799
init_layer3(fr.down_sample);
801
#if !defined(WIN32) && !defined(GENERIC)
802
/* This ctrl+c for title skip only when not in some control mode */
810
catchsignal (SIGINT, catch_interrupt);
815
ret = control_generic(&fr);
821
init_id3(); /* prepare id3 memory */
822
while ((fname = get_next_file())) {
823
char *dirname, *filename;
824
long leftFrames,newFrame;
826
if(!*fname || !strcmp(fname, "-"))
828
if (open_stream(fname,-1) < 0)
832
if (split_dir_file(fname ? fname : "standard input",
833
&dirname, &filename))
834
fprintf(stderr, "\nDirectory: %s", dirname);
835
fprintf(stderr, "\nPlaying MPEG stream %lu of %lu: %s ...\n", (unsigned long)pl.pos, (unsigned long)pl.fill, filename);
837
#if !defined(GENERIC)
839
const char *term_type;
840
term_type = getenv("TERM");
841
if (term_type && param.xterm_title &&
842
(!strncmp(term_type,"xterm",5) || !strncmp(term_type,"rxvt",4)))
844
fprintf(stderr, "\033]0;%s\007", filename);
851
#if !defined(WIN32) && !defined(GENERIC)
855
gettimeofday (&start_time, NULL);
857
read_frame_init(&fr);
863
newFrame = startFrame;
866
debug1("param.term_ctrl: %i", param.term_ctrl);
870
leftFrames = numframes;
871
/* read_frame is counting the frames! */
872
for(;read_frame(&fr) && leftFrames && !intflag;) {
876
if(fr.num < startFrame || (param.doublespeed && (fr.num % param.doublespeed))) {
885
prepare_audioinfo(&fr, &pre_ai);
889
layer3_gapless_set_position(fr.num, &fr, &pre_ai);
897
play_frame(init,&fr);
902
if (param.verbose > 1 || !(fr.num & 0x7))
903
print_stat(&fr,fr.num,xfermem_get_usedspace(buffermem),&ai);
904
if(param.verbose > 2 && param.usebuffer)
905
fprintf(stderr,"[%08x %08x]",buffermem->readindex,buffermem->freeindex);
907
if (param.verbose > 1 || !(fr.num & 0x7))
908
print_stat(&fr,fr.num,0,&ai);
912
if(!param.term_ctrl) {
916
if((offset=term_control(&fr))) {
917
if(!rd->back_frame(rd, &fr, -offset)) {
918
debug1("seeked to %lu", fr.num);
920
if(param.gapless && (fr.lay == 3))
921
layer3_gapless_set_position(fr.num, &fr, &ai);
923
} else { error("seek failed!"); }
930
/* make sure that the correct padding is skipped after track ended */
931
if(param.gapless) audio_flush(param.outmode, &ai);
935
if(param.usebuffer) {
937
while ((s = xfermem_get_usedspace(buffermem))) {
938
struct timeval wait170 = {0, 170000};
940
buffer_ignore_lowmem();
943
print_stat(&fr,fr.num,s,&ai);
945
if(param.term_ctrl) {
947
if((offset=term_control(&fr))) {
948
if((!rd->back_frame(rd, &fr, -offset))
951
debug1("seeked to %lu", fr.num);
953
if(param.gapless && (fr.lay == 3))
954
layer3_gapless_set_position(fr.num, &fr, &ai);
956
goto tc_hack; /* Doh! Gag me with a spoon! */
957
} else { error("seek failed!"); }
961
select(0, NULL, NULL, NULL, &wait170);
966
print_stat(&fr,fr.num,xfermem_get_usedspace(buffermem),&ai);
974
* This formula seems to work at least for
975
* MPEG 1.0/2.0 layer 3 streams.
977
int secs = get_songlen(&fr,fr.num);
978
fprintf(stderr,"\n[%d:%02d] Decoding of %s finished.\n", secs / 60,
979
secs % 60, filename);
985
fprintf(stderr,"@R MPG123\n");
995
* When HAVE_TERMIOS is defined, there is 'q' to terminate a list of songs, so
996
* no pressing need to keep up this first second SIGINT hack that was too
997
* often mistaken as a bug. [dk]
998
* ThOr: Yep, I deactivated the Ctrl+C hack for active control modes.
1000
#if !defined(WIN32) && !defined(GENERIC)
1002
if(!param.term_ctrl)
1005
gettimeofday (&now, NULL);
1006
secdiff = (now.tv_sec - start_time.tv_sec) * 1000;
1007
if (now.tv_usec >= start_time.tv_usec)
1008
secdiff += (now.tv_usec - start_time.tv_usec) / 1000;
1010
secdiff -= (start_time.tv_usec - now.tv_usec) / 1000;
1018
if(param.usebuffer) buffer_resync();
1021
} /* end of loop over input files */
1022
exit_id3(); /* free id3 memory */
1024
if (param.usebuffer) {
1026
xfermem_done_writer (buffermem);
1027
waitpid (buffer_pid, NULL, 0);
1028
xfermem_done (buffermem);
1032
audio_flush(param.outmode, &ai);
1038
switch(param.outmode) {
1052
if(!param.remote) free_playlist();
1056
static void print_title(FILE *o)
1058
fprintf(o, "High Performance MPEG 1.0/2.0/2.5 Audio Player for Layers 1, 2 and 3\n");
1059
fprintf(o, "\tversion %s; written and copyright by Michael Hipp and others\n", PACKAGE_VERSION);
1060
fprintf(o, "\tfree software (LGPL/GPL) without any warranty but with best wishes\n");
1063
static void usage(int err) /* print syntax & exit */
1069
fprintf(o, "You made some mistake in program usage... let me briefly remind you:\n\n");
1072
fprintf(o,"\nusage: %s [option(s)] [file(s) | URL(s) | -]\n", prgName);
1073
fprintf(o,"supported options [defaults in brackets]:\n");
1074
fprintf(o," -v increase verbosity level -q quiet (don't print title)\n");
1075
fprintf(o," -t testmode (no output) -s write to stdout\n");
1076
fprintf(o," -w <filename> write Output as WAV file\n");
1077
fprintf(o," -k n skip first n frames [0] -n n decode only n frames [all]\n");
1078
fprintf(o," -c check range violations -y DISABLE resync on errors\n");
1079
fprintf(o," -b n output buffer: n Kbytes [0] -f n change scalefactor [32768]\n");
1080
fprintf(o," -r n set/force samplerate [auto] -g n set audio hardware output gain\n");
1081
fprintf(o," -os,-ol,-oh output to built-in speaker,line-out connector,headphones\n");
1083
fprintf(o," -a d set NAS server\n");
1085
fprintf(o," -a [1..4] set RAD device\n");
1087
fprintf(o," -a d set audio device\n");
1089
fprintf(o," -2 downsample 1:2 (22 kHz) -4 downsample 1:4 (11 kHz)\n");
1090
fprintf(o," -d n play every n'th frame only -h n play every frame n times\n");
1091
fprintf(o," -0 decode channel 0 (left) only -1 decode channel 1 (right) only\n");
1092
fprintf(o," -m mix both channels (mono) -p p use HTTP proxy p [$HTTP_PROXY]\n");
1093
#ifdef HAVE_SCHED_SETSCHEDULER
1094
fprintf(o," -@ f read filenames/URLs from f -T get realtime priority\n");
1096
fprintf(o," -@ f read filenames/URLs from f\n");
1098
fprintf(o," -z shuffle play (with wildcards) -Z random play\n");
1099
fprintf(o," -u a HTTP authentication string -E f Equalizer, data from file\n");
1101
fprintf(o," -C enable control keys --gapless skip junk/padding in some mp3s\n");
1103
fprintf(o," -C enable control keys\n");
1105
fprintf(o," -? this help --version print name + version\n");
1106
fprintf(o,"See the manpage %s(1) or call %s with --longhelp for more parameters and information.\n", prgName,prgName);
1110
static void want_usage(char* arg)
1115
static void long_usage(int err)
1121
fprintf(o, "You made some mistake in program usage... let me remind you:\n\n");
1124
fprintf(o,"\nusage: %s [option(s)] [file(s) | URL(s) | -]\n", prgName);
1126
fprintf(o,"\ninput options\n\n");
1127
fprintf(o," -k <n> --skip <n> skip n frames at beginning\n");
1128
fprintf(o," -n --frames <n> play only <n> frames of every stream\n");
1129
fprintf(o," -y --resync DISABLES resync on error\n");
1130
fprintf(o," -p <f> --proxy <f> set WWW proxy\n");
1131
fprintf(o," -u --auth set auth values for HTTP access\n");
1132
fprintf(o," -@ <f> --list <f> play songs in playlist <f> (plain list, m3u, pls (shoutcast))\n");
1133
fprintf(o," -l <n> --listentry <n> play nth title in playlist; show whole playlist for n < 0\n");
1134
fprintf(o," -z --shuffle shuffle song-list before playing\n");
1135
fprintf(o," -Z --random full random play\n");
1137
fprintf(o,"\noutput/processing options\n\n");
1138
fprintf(o," -a <d> --audiodevice <d> select audio device\n");
1139
fprintf(o," -s --stdout write raw audio to stdout (host native format)\n");
1140
fprintf(o," -S --STDOUT play AND output stream (not implemented yet)\n");
1141
fprintf(o," -w <f> --wav <f> write samples as WAV file in <f> (- is stdout)\n");
1142
fprintf(o," --au <f> write samples as Sun AU file in <f> (- is stdout)\n");
1143
fprintf(o," --cdr <f> write samples as CDR file in <f> (- is stdout)\n");
1144
fprintf(o," --reopen force close/open on audiodevice\n");
1145
fprintf(o," -g --gain set audio hardware output gain\n");
1146
fprintf(o," -f <n> --scale <n> scale output samples (soft gain, default=%li)\n", outscale);
1147
fprintf(o," --rva-mix,\n");
1148
fprintf(o," --rva-radio use RVA2/ReplayGain values for mix/radio mode\n");
1149
fprintf(o," --rva-album,\n");
1150
fprintf(o," --rva-audiophile use RVA2/ReplayGain values for album/audiophile mode\n");
1151
fprintf(o," --reopen force close/open on audiodevice\n");
1152
fprintf(o," -0 --left --single0 play only left channel\n");
1153
fprintf(o," -1 --right --single1 play only right channel\n");
1154
fprintf(o," -m --mono --mix mix stereo to mono\n");
1155
fprintf(o," --stereo duplicate mono channel\n");
1156
fprintf(o," -r --rate force a specific audio output rate\n");
1157
fprintf(o," -2 --2to1 2:1 downsampling\n");
1158
fprintf(o," -4 --4to1 4:1 downsampling\n");
1159
fprintf(o," --8bit force 8 bit output\n");
1160
fprintf(o," -d --doublespeed play only every second frame\n");
1161
fprintf(o," -h --halfspeed play every frame twice\n");
1162
fprintf(o," --equalizer exp.: scales freq. bands acrd. to 'equalizer.dat'\n");
1164
fprintf(o," --gapless remove padding/junk added by encoder/decoder\n");
1166
fprintf(o," (experimental, needs Lame tag, layer 3 only)\n");
1167
fprintf(o," -o h --headphones (aix/hp/sun) output on headphones\n");
1168
fprintf(o," -o s --speaker (aix/hp/sun) output on speaker\n");
1169
fprintf(o," -o l --lineout (aix/hp/sun) output to lineout\n");
1170
fprintf(o," -b <n> --buffer <n> set play buffer (\"output cache\")\n");
1172
fprintf(o,"\nmisc options\n\n");
1173
fprintf(o," -t --test only decode, no output (benchmark)\n");
1174
fprintf(o," -c --check count and display clipped samples\n");
1175
fprintf(o," -v[*] --verbose increase verboselevel\n");
1176
fprintf(o," -q --quiet quiet mode\n");
1178
fprintf(o," -C --control enable terminal control keys\n");
1181
fprintf(o," --title set xterm/rxvt title to filename\n");
1183
fprintf(o," -R --remote generic remote interface\n");
1184
fprintf(o," --remote-err use stderr for generic remote interface\n");
1185
#ifdef HAVE_SETPRIORITY
1186
fprintf(o," --aggressive tries to get higher priority (nice)\n");
1188
#ifdef HAVE_SCHED_SETSCHEDULER
1189
fprintf(o," -T --realtime tries to get realtime priority\n");
1192
fprintf(o," --test-3dnow display result of 3DNow! autodetect and exit\n");
1193
fprintf(o," --force-3dnow force use of 3DNow! optimized routine\n");
1194
fprintf(o," --no-3dnow force use of floating-pointer routine\n");
1196
fprintf(o," -? --help give compact help\n");
1197
fprintf(o," --longhelp give this long help listing\n");
1198
fprintf(o," --version give name / version string\n");
1200
fprintf(o,"\nSee the manpage %s(1) for more information.\n", prgName);
1204
static void want_long_usage(char* arg)
1209
static void give_version(char* arg)
1211
fprintf(stdout, PACKAGE_NAME" "PACKAGE_VERSION"\n");