home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1998 June B
/
Pcwk6b98.iso
/
Mpeg3
/
Dos
/
MP3
/
MPG12304.EXE
/
MPG123.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-05-10
|
9KB
|
270 lines
/*
* Mpeg Layer audio decoder V0.58
* -------------------------------
* copyright (c) 1995,1996,1997 by Michael Hipp, All rights reserved.
* See also 'README' !
*
* used sources:
* mpegaudio package
*/
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
/* #define SET_PRIO */
#include "mpg123.h"
#include "getlopt.h"
char *prgVersion = "0.58";
char *prgDate = "97/04/10";
char *prgName;
static void usage(char *dummy);
static void print_title(void);
int outmode = DECODE_AUDIO;
char *listname = NULL;
int intflag = FALSE;
long outscale = 32768;
int checkrange = FALSE;
int tryresync = FALSE;
int verbose = FALSE;
int quiet = FALSE;
int doublespeed= 0;
int halfspeed = 0;
long numframes = -1;
long startFrame= 0;
static struct frame fr;
static struct audio_info_struct ai;
void init_output(void)
{
static int init_done = FALSE;
if (init_done)
return;
init_done = TRUE;
if(outmode==DECODE_AUDIO) {
if(audio_open(&ai) < 0) {
perror("audio");
exit(1);
}
audio_set_rate (&ai);
}
}
char *get_next_file (int argc, char *argv[])
{
static FILE *listfile = NULL;
static char line[1024];
if (listname || listfile) {
if (!listfile) {
if (!*listname || !strcmp(listname, "-")) {
listfile = stdin;
listname = NULL;
}
else if (!(listfile = fopen(listname, "rb"))) {
perror (listname);
exit (1);
}
if (verbose)
fprintf (stderr, "Using playlist from %s ...\n",
listname ? listname : "standard input");
}
do {
if (fgets(line, 1023, listfile)) {
line[strcspn(line, "\t\n\r")] = '\0';
if (line[0]=='\0' || line[0]=='#')
continue;
return (line);
}
else {
if (*listname)
fclose (listfile);
listname = NULL;
listfile = NULL;
}
} while (listfile);
}
if (loptind < argc)
return (argv[loptind++]);
return (NULL);
}
void set_synth (char *arg)
{
if (*arg == '2')
fr.synth = synth_2to1;
else
fr.synth = synth_4to1;
}
#ifdef VARMODESUPPORT
void set_varmode (char *arg)
{
audiobufsize = ((audiobufsize >> 1) + 63) & 0xffffc0;
}
#endif
topt opts[] = {
{'k', "skip", GLO_ARG | GLO_NUM, 0, &startFrame, 0},
{'2', "2to1", 0, set_synth, 0, 0},
{'4', "4to1", 0, set_synth, 0, 0},
{'t', "test", 0, 0, &outmode, DECODE_TEST},
{'c', "check", 0, 0, &checkrange, TRUE},
{'v', "verbose", 0, 0, &verbose, TRUE},
{'q', "quiet", 0, 0, &quiet, TRUE},
{'y', "resync", 0, 0, &tryresync, TRUE},
{'0', "single0", 0, 0, &fr.single, 0},
{0, "left", 0, 0, &fr.single, 0},
{'1', "single1", 0, 0, &fr.single, 1},
{0, "right", 0, 0, &fr.single, 1},
{'m', "singlemix", 0, 0, &fr.single, 3},
{0, "mix", 0, 0, &fr.single, 3},
{'g', "gain", GLO_ARG | GLO_NUM, 0, &ai.gain, 0},
{'r', "rate", GLO_ARG | GLO_NUM, 0, &ai.rate, 0},
{'f', "scale", GLO_ARG | GLO_NUM, 0, &outscale, 0},
{'n', "frames", GLO_ARG | GLO_NUM, 0, &numframes, 0},
#ifdef VARMODESUPPORT
{'v', "var", 0, set_varmode, &varmode, TRUE},
#endif
{'d', "doublespeed", GLO_ARG | GLO_NUM, 0, &doublespeed,0},
{'h', "halfspeed", GLO_ARG | GLO_NUM, 0, &halfspeed, 0},
{'@', "list", GLO_ARG | GLO_CHAR, 0, &listname, 0},
{'?', "help", 0, usage, 0, 0}
};
int main(int argc, char *argv[])
{
int result, stereo, clip=0;
int crc_error_count, total_error_count;
unsigned int old_crc;
unsigned long frameNum = 0;
char *fname;
unsigned long secdiff;
fr.single = -1; /* both channels */
fr.synth = synth_1to1;
ai.gain = ai.rate = ai.output = -1;
ai.device = NULL;
ai.channels = 2;
(prgName = strrchr(argv[0], '/')) ? prgName++ : (prgName = argv[0]);
while ((result = getlopt(argc, argv, opts)))
switch (result) {
case GLO_UNKNOWN:
fprintf (stderr, "%s: Unknown option \"%s\".", prgName, loptarg);
exit (1);
case GLO_NOARG:
fprintf (stderr, "%s: Missing argument for option \"%s\".",
prgName, loptarg);
exit (1);
}
if (loptind >= argc && !listname)
usage(NULL);
if (!quiet)
print_title();
make_decode_tables(outscale);
init_layer2(); /* inits also shared tables with layer1 */
init_layer3();
while ((fname = get_next_file(argc, argv))) {
if(!*fname || !strcmp(fname, "-"))
fname = NULL;
open_stream(fname);
if (!quiet)
fprintf(stderr, "\nPlaying MPEG stream from %s ...\n",
fname ? fname : "standard input");
for(frameNum=0;read_frame(&fr) && numframes && !intflag;frameNum++)
{
stereo = fr.stereo;
crc_error_count = 0;
total_error_count = 0;
if(!frameNum)
{
if (!quiet)
print_header(&fr);
if(ai.rate == -1) {
ai.rate = freqs[fr.sampling_frequency];
}
init_output();
}
if(frameNum < startFrame || (doublespeed && (frameNum % doublespeed))) {
if(fr.lay == 3) {
set_pointer(512);
}
continue;
}
numframes--;
if (fr.error_protection)
old_crc = getbits(16);
switch(fr.lay)
{
case 1:
clip = do_layer1(&fr,outmode,&ai);
break;
case 2:
clip = do_layer2(&fr,outmode,&ai);
break;
case 3:
clip = do_layer3(&fr,outmode,&ai);
break;
}
if(verbose)
fprintf(stderr, "\r{%5lu}",frameNum);
if(clip > 0 && checkrange)
fprintf(stderr,"%d samples clipped\n", clip);
}
close_stream(fname);
if (!quiet)
fprintf(stderr,"Decoding of %s finished.\n",
fname ? fname : "standard input");
}
audio_flush(outmode, &ai);
if(outmode==DECODE_AUDIO)
audio_close(&ai);
exit( 0 );
return 0;
}
static void print_title(void)
{
fprintf(stderr,"High Performance MPEG 1.0 Audio Player for Layer 1,2 and 3. ..\n");
fprintf(stderr,"Version %s (%s). Mostly written and copyrighted by\n", prgVersion, prgDate);
fprintf(stderr,"Michael Hipp and Tuomas Leikola. Uses code from various people. \n");
fprintf(stderr,"See 'README' for more!\n");
}
static void usage(char *dummy) /* print syntax & exit */
{
print_title();
fprintf(stderr,"\nusage: %s [option(s)] [file(s) | URL(s) | -]\n", prgName);
fprintf(stderr,"supported options [defaults in brackets]:\n");
fprintf(stderr," -v verbose -q quiet\n");
fprintf(stderr," -t testmode (no output) -s write to stdout\n");
fprintf(stderr," -k n skip first n frames [0] -n n decode only n frames [all]\n");
fprintf(stderr," -c check range violations -y try to resync on errors\n");
fprintf(stderr," -b n output buffer: n Kbytes [0] -f n change scalefactor [32768]\n");
fprintf(stderr," -r n override samplerate [auto] -g n set audio hardware output gain\n");
fprintf(stderr," -2 downsample 1:2 (22 kHz) -4 downsample 1:4 (11 kHz)\n");
fprintf(stderr," -d n play every n'th frame only -h n play every frame n times\n");
fprintf(stderr," -0 decode channel 0 (left) only -1 decode channel 1 (right) only\n");
fprintf(stderr," -m mix both channels (mono) -@ f read filenames from f\n");
fprintf(stderr,"See the mpg123.doc for more info.\n");
exit(1);
}