home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 June B / Pcwk6b98.iso / Mpeg3 / Dos / MP3 / MPG12304.EXE / MPG123.C < prev    next >
C/C++ Source or Header  |  1997-05-10  |  9KB  |  270 lines

  1. /* 
  2.  * Mpeg Layer audio decoder V0.58
  3.  * -------------------------------
  4.  * copyright (c) 1995,1996,1997 by Michael Hipp, All rights reserved.
  5.  * See also 'README' !
  6.  *
  7.  * used sources:
  8.  *   mpegaudio package
  9.  */
  10.  
  11. #include <stdlib.h>
  12. #include <signal.h>
  13. #include <sys/types.h>
  14.  
  15. /* #define SET_PRIO */
  16.  
  17. #include "mpg123.h"
  18. #include "getlopt.h"
  19.  
  20. char *prgVersion = "0.58";
  21. char *prgDate = "97/04/10";
  22. char *prgName;
  23.  
  24. static void usage(char *dummy);
  25. static void print_title(void);
  26.  
  27. int outmode = DECODE_AUDIO;
  28.  
  29. char *listname = NULL;
  30. int intflag    = FALSE;
  31. long outscale  = 32768;
  32. int checkrange = FALSE;
  33. int tryresync  = FALSE;
  34. int verbose    = FALSE;
  35. int quiet      = FALSE;
  36. int doublespeed= 0;
  37. int halfspeed  = 0;
  38. long numframes = -1;
  39. long startFrame= 0;
  40.  
  41. static struct frame fr;
  42. static struct audio_info_struct ai;
  43.  
  44. void init_output(void)
  45. {
  46.   static int init_done = FALSE;
  47.  
  48.   if (init_done)
  49.     return;
  50.   init_done = TRUE;
  51.   if(outmode==DECODE_AUDIO) {
  52.     if(audio_open(&ai) < 0) {
  53.       perror("audio");
  54.       exit(1);
  55.     }
  56.     audio_set_rate (&ai);
  57.   }
  58. }
  59.  
  60. char *get_next_file (int argc, char *argv[])
  61. {
  62.     static FILE *listfile = NULL;
  63.     static char line[1024];
  64.  
  65.     if (listname || listfile) {
  66.         if (!listfile) {
  67.             if (!*listname || !strcmp(listname, "-")) {
  68.                 listfile = stdin;
  69.                 listname = NULL;
  70.             }
  71.             else if (!(listfile = fopen(listname, "rb"))) {
  72.                 perror (listname);
  73.                 exit (1);
  74.             }
  75.             if (verbose)
  76.                 fprintf (stderr, "Using playlist from %s ...\n",
  77.                         listname ? listname : "standard input");
  78.         }
  79.         do {
  80.             if (fgets(line, 1023, listfile)) {
  81.                 line[strcspn(line, "\t\n\r")] = '\0';
  82.                 if (line[0]=='\0' || line[0]=='#')
  83.                     continue;
  84.                 return (line);
  85.             }
  86.             else {
  87.                 if (*listname)
  88.                    fclose (listfile);
  89.                 listname = NULL;
  90.                 listfile = NULL;
  91.             }
  92.         } while (listfile);
  93.     }
  94.     if (loptind < argc)
  95.         return (argv[loptind++]);
  96.     return (NULL);
  97. }
  98.  
  99. void set_synth (char *arg)
  100. {
  101.     if (*arg == '2')
  102.         fr.synth = synth_2to1;
  103.     else
  104.         fr.synth = synth_4to1;
  105. }
  106.  
  107. #ifdef VARMODESUPPORT
  108. void set_varmode (char *arg)
  109. {
  110.     audiobufsize = ((audiobufsize >> 1) + 63) & 0xffffc0;
  111. }
  112. #endif
  113.  
  114. topt opts[] = {
  115.     {'k', "skip",        GLO_ARG | GLO_NUM,  0, &startFrame, 0},
  116.     {'2', "2to1",        0,          set_synth, 0,           0},
  117.     {'4', "4to1",        0,          set_synth, 0,           0},
  118.     {'t', "test",        0,                  0, &outmode, DECODE_TEST},
  119.     {'c', "check",       0,                  0, &checkrange, TRUE},
  120.     {'v', "verbose",     0,                  0, &verbose,    TRUE},
  121.     {'q', "quiet",       0,                  0, &quiet,      TRUE},
  122.     {'y', "resync",      0,                  0, &tryresync,  TRUE},
  123.     {'0', "single0",     0,                  0, &fr.single,  0},
  124.     {0,   "left",        0,                  0, &fr.single,  0},
  125.     {'1', "single1",     0,                  0, &fr.single,  1},
  126.     {0,   "right",       0,                  0, &fr.single,  1},
  127.     {'m', "singlemix",   0,                  0, &fr.single,  3},
  128.     {0,   "mix",         0,                  0, &fr.single,  3},
  129.     {'g', "gain",        GLO_ARG | GLO_NUM,  0, &ai.gain,    0},
  130.     {'r', "rate",        GLO_ARG | GLO_NUM,  0, &ai.rate,    0},
  131.     {'f', "scale",       GLO_ARG | GLO_NUM,  0, &outscale,   0},
  132.     {'n', "frames",      GLO_ARG | GLO_NUM,  0, &numframes,  0},
  133. #ifdef VARMODESUPPORT
  134.     {'v', "var",         0,        set_varmode, &varmode,    TRUE},
  135. #endif
  136.     {'d', "doublespeed", GLO_ARG | GLO_NUM,  0, &doublespeed,0},
  137.     {'h', "halfspeed",   GLO_ARG | GLO_NUM,  0, &halfspeed,  0},
  138.     {'@', "list",        GLO_ARG | GLO_CHAR, 0, &listname,   0},
  139.     {'?', "help",        0,              usage, 0,           0}
  140. };
  141.  
  142. int main(int argc, char *argv[])
  143. {
  144.     int result, stereo, clip=0;
  145.     int crc_error_count, total_error_count;
  146.     unsigned int old_crc;
  147.     unsigned long frameNum = 0;
  148.     char *fname;
  149.     unsigned long secdiff;
  150.  
  151.     fr.single = -1; /* both channels */
  152.     fr.synth = synth_1to1;
  153.  
  154.     ai.gain = ai.rate = ai.output = -1;
  155.     ai.device = NULL;
  156.     ai.channels = 2;
  157.  
  158.     (prgName = strrchr(argv[0], '/')) ? prgName++ : (prgName = argv[0]);
  159.  
  160.     while ((result = getlopt(argc, argv, opts)))
  161.       switch (result) {
  162.         case GLO_UNKNOWN:
  163.           fprintf (stderr, "%s: Unknown option \"%s\".", prgName, loptarg);
  164.           exit (1);
  165.         case GLO_NOARG:
  166.           fprintf (stderr, "%s: Missing argument for option \"%s\".",
  167.               prgName, loptarg);
  168.           exit (1);
  169.       }
  170.     if (loptind >= argc && !listname)
  171.       usage(NULL);
  172.  
  173.     if (!quiet)
  174.       print_title();
  175.  
  176.     make_decode_tables(outscale);
  177.     init_layer2(); /* inits also shared tables with layer1 */
  178.     init_layer3();
  179.  
  180.     while ((fname = get_next_file(argc, argv))) {
  181.       if(!*fname || !strcmp(fname, "-"))
  182.         fname = NULL;
  183.       open_stream(fname);
  184.       if (!quiet)
  185.         fprintf(stderr, "\nPlaying MPEG stream from %s ...\n",
  186.                 fname ? fname : "standard input");
  187.  
  188.       for(frameNum=0;read_frame(&fr) && numframes && !intflag;frameNum++) 
  189.       {
  190.          stereo = fr.stereo;
  191.          crc_error_count   = 0;
  192.          total_error_count = 0;
  193.  
  194.          if(!frameNum)
  195.          {
  196.            if (!quiet)
  197.              print_header(&fr);
  198.            if(ai.rate == -1) {
  199.              ai.rate = freqs[fr.sampling_frequency];
  200.            }
  201.            init_output();
  202.          }
  203.          if(frameNum < startFrame || (doublespeed && (frameNum % doublespeed))) {
  204.            if(fr.lay == 3) {
  205.              set_pointer(512);
  206.            }
  207.            continue;
  208.          }
  209.          numframes--;
  210.  
  211.          if (fr.error_protection)
  212.             old_crc = getbits(16);
  213.  
  214.          switch(fr.lay)
  215.          {
  216.            case 1:
  217.              clip = do_layer1(&fr,outmode,&ai);
  218.              break;
  219.            case 2:
  220.              clip = do_layer2(&fr,outmode,&ai);
  221.              break;
  222.            case 3:
  223.              clip = do_layer3(&fr,outmode,&ai);
  224.              break;
  225.          }
  226.          if(verbose)
  227.            fprintf(stderr, "\r{%5lu}",frameNum);
  228.          if(clip > 0 && checkrange)
  229.            fprintf(stderr,"%d samples clipped\n", clip);
  230.       }
  231.       close_stream(fname);
  232.       if (!quiet)
  233.         fprintf(stderr,"Decoding of %s finished.\n",
  234.                 fname ? fname : "standard input");
  235.     }
  236.     audio_flush(outmode, &ai);
  237.  
  238.     if(outmode==DECODE_AUDIO)
  239.       audio_close(&ai);
  240.     exit( 0 );
  241.     return 0;
  242. }
  243.  
  244. static void print_title(void)
  245. {
  246.     fprintf(stderr,"High Performance MPEG 1.0 Audio Player for Layer 1,2 and 3. ..\n");
  247.     fprintf(stderr,"Version %s (%s). Mostly written and copyrighted by\n", prgVersion, prgDate);
  248.     fprintf(stderr,"Michael Hipp and Tuomas Leikola. Uses code from various people. \n");
  249.     fprintf(stderr,"See 'README' for more!\n");
  250. }
  251.  
  252. static void usage(char *dummy)  /* print syntax & exit */
  253. {
  254.   print_title();
  255.   fprintf(stderr,"\nusage: %s [option(s)] [file(s) | URL(s) | -]\n", prgName);
  256.   fprintf(stderr,"supported options [defaults in brackets]:\n");
  257.   fprintf(stderr,"   -v    verbose                        -q    quiet\n");
  258.   fprintf(stderr,"   -t    testmode (no output)           -s    write to stdout\n");
  259.   fprintf(stderr,"   -k n  skip first n frames [0]        -n n  decode only n frames [all]\n");
  260.   fprintf(stderr,"   -c    check range violations         -y    try to resync on errors\n");
  261.   fprintf(stderr,"   -b n  output buffer: n Kbytes [0]    -f n  change scalefactor [32768]\n");
  262.   fprintf(stderr,"   -r n  override samplerate [auto]     -g n  set audio hardware output gain\n");
  263.   fprintf(stderr,"   -2    downsample 1:2 (22 kHz)        -4    downsample 1:4 (11 kHz)\n");
  264.   fprintf(stderr,"   -d n  play every n'th frame only     -h n  play every frame n times\n");
  265.   fprintf(stderr,"   -0    decode channel 0 (left) only   -1    decode channel 1 (right) only\n");
  266.   fprintf(stderr,"   -m    mix both channels (mono)       -@ f  read filenames from f\n");
  267.   fprintf(stderr,"See the mpg123.doc for more info.\n");
  268.   exit(1);
  269. }
  270.