home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD1.iso / GFX / MPEG / mpeg3play.lha / mpeg3play / src / musicout.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-12  |  25.9 KB  |  832 lines

  1. /**********************************************************************
  2.  * ISO MPEG Audio Subgroup Software Simulation Group (1996)
  3.  * ISO 13818-3 MPEG-2 Audio Decoder - Lower Sampling Frequency Extension
  4.  *
  5.  * $Id: musicout.c,v 1.2 1996/03/28 03:13:37 rowlands Exp $
  6.  *
  7.  * $Log: musicout.c,v $
  8.  * Revision 1.2  1996/03/28 03:13:37  rowlands
  9.  * Merged layers 1-2 and layer 3 revisions
  10.  *
  11.  * Revision 1.1  1996/02/14 03:45:52  rowlands
  12.  * Initial revision
  13.  *
  14.  * Received from FhG
  15.  **********************************************************************/
  16. /**********************************************************************
  17.  *   date   programmers                comment                        *
  18.  * 2/25/91  Douglas Wong        start of version 1.0 records          *
  19.  * 3/06/91  Douglas Wong        rename setup.h to dedef.h             *
  20.  *                              removed extraneous variables          *
  21.  *                              removed window_samples (now part of   *
  22.  *                              filter_samples)                       *
  23.  * 3/07/91  Davis Pan           changed output file to "codmusic"     *
  24.  * 5/10/91  Vish (PRISM)        Ported to Macintosh and Unix.         *
  25.  *                              Incorporated new "out_fifo()" which   *
  26.  *                              writes out last incomplete buffer.    *
  27.  *                              Incorporated all AIFF routines which  *
  28.  *                              are also compatible with SUN.         *
  29.  *                              Incorporated user interface for       *
  30.  *                              specifying sound file names.          *
  31.  *                              Also incorporated user interface for  *
  32.  *                              writing AIFF compatible sound files.  *
  33.  * 27jun91  dpwe (Aware)        Added musicout and &sample_frames as  *
  34.  *                              args to out_fifo (were glob refs).    *
  35.  *                              Used new 'frame_params' struct.       *
  36.  *                              Clean,simplify, track clipped output  *
  37.  *                              and total bits/frame received.        *
  38.  * 7/10/91  Earle Jennings      changed to floats to FLOAT            *
  39.  *10/ 1/91  S.I. Sudharsanan,   Ported to IBM AIX platform.           *
  40.  *          Don H. Lee,                                               *
  41.  *          Peter W. Farrett                                          *
  42.  *10/ 3/91  Don H. Lee          implemented CRC-16 error protection   *
  43.  *                              newly introduced functions are        *
  44.  *                              buffer_CRC and recover_CRC_error      *
  45.  *                              Additions and revisions are marked    *
  46.  *                              with "dhl" for clarity                *
  47.  * 2/11/92  W. Joseph Carter    Ported new code to Macintosh.  Most   *
  48.  *                              important fixes involved changing     *
  49.  *                              16-bit ints to long or unsigned in    *
  50.  *                              bit alloc routines for quant of 65535 *
  51.  *                              and passing proper function args.     *
  52.  *                              Removed "Other Joint Stereo" option   *
  53.  *                              and made bitrate be total channel     *
  54.  *                              bitrate, irrespective of the mode.    *
  55.  *                              Fixed many small bugs & reorganized.  *
  56.  *19 aug 92 Soren H. Nielsen    Changed MS-DOS file name extensions.  *
  57.  * 8/27/93 Seymour Shlien,      Fixes in Unix and MSDOS ports,        *
  58.  *         Daniel Lauzon, and                                         *
  59.  *         Bill Truerniet                                             *
  60.  *--------------------------------------------------------------------*
  61.  * 4/23/92  J. Pineda           Added code for layer III.  LayerIII   *
  62.  *          Amit Gulati         decoding is currently performed in    *
  63.  *                              two-passes for ease of sideinfo and   *
  64.  *                              maindata buffering and decoding.      *
  65.  *                              The second (computation) pass is      *
  66.  *                              activated with "decode -3 <outfile>"  *
  67.  * 10/25/92 Amit Gulati         Modified usage() for layerIII         *
  68.  * 12/10/92 Amit Gulati         Changed processing order of re-order- *
  69.  *                              -ing step.  Fixed adjustment of       *
  70.  *                              main_data_end pointer to exclude      *
  71.  *                              side information.                     *
  72.  *  9/07/93 Toshiyuki Ishino    Integrated Layer III with Ver 3.9.    *
  73.  *--------------------------------------------------------------------*
  74.  * 11/20/93 Masahiro Iwadare    Integrated Layer III with Ver 4.0.    *
  75.  *--------------------------------------------------------------------*
  76.  *  7/14/94 Juergen Koller      Bug fixes in Layer III code           *
  77.  *--------------------------------------------------------------------*
  78.  * 08/11/94 IIS                 Bug fixes in Layer III code           *
  79.  *--------------------------------------------------------------------*
  80.  * 11/04/94 Jon Rowlands        Prototype fixes                       *
  81.  *--------------------------------------------------------------------*
  82.  *  7/12/95 Soeren H. Nielsen   Changes for LSF Layer I and II        *
  83.  *--------------------------------------------------------------------*
  84.  *  7/14/94 Juergen Koller      Bug fixes in Layer III code           *
  85.  *--------------------------------------------------------------------*
  86.  *     8/95 Roland Bitto        addapdet to MPEG 2                    *
  87.  *--------------------------------------------------------------------*
  88.  * 11/22/95 Heiko Purnhagen     skip ancillary data in bitstream      *
  89.  *--------------------------------------------------------------------*
  90.  * 12/16/96 Johan Hagman    Adapted for Solaris (mpeg3play 0.9)   *
  91.  **********************************************************************/
  92.  
  93. #include        "common.h"
  94. #include        "decoder.h"
  95.  
  96. /********************************************************************
  97.  *
  98.  *        This part contains the MPEG I decoder for Layers I & II.
  99.  *
  100.  *********************************************************************/
  101.  
  102. /****************************************************************
  103.  *
  104.  *        For MS-DOS user (Turbo c) change all instance of malloc
  105.  *        to _farmalloc and free to _farfree. Compiler model hugh
  106.  *        Also make sure all the pointer specified are changed to far.
  107.  *
  108.  *****************************************************************/
  109. /* local functions definition */
  110.  
  111. static void usage(int level);
  112. static void GetArguments();
  113. static void init_sound(layer *info, int stereo);
  114.  
  115. /*********************************************************************
  116.  *
  117.  * Core of the Layer II decoder.  Default layer is Layer II.
  118.  *
  119.  *********************************************************************/
  120.  
  121. /* Global variable definitions for "musicout.c" */
  122.  
  123. char        *programName;
  124. Arguments_t     Arguments;
  125. int         audiofd;
  126. /* Workaround for an audio buffer bug/restriction on Ultra/Solaris 2.5 */
  127. int         smallAudioBuffer = 0;
  128.  
  129. int         main_data_slots();
  130. int         side_info_slots();
  131.  
  132. /* Implementations */
  133.  
  134. int main(int argc, char **argv)
  135. {
  136.     typedef unsigned int SAM[2][3][SBLIMIT];
  137.     static SAM FAR    *sample;
  138.  
  139.     typedef REAL     FRA[2][3][SBLIMIT];
  140.     static FRA FAR    *fraction;
  141.  
  142.     typedef short     PCM[2][SSLIMIT][SBLIMIT];
  143.     static PCM FAR    *pcm_sample;
  144.  
  145.     static Bit_stream_struc bs;
  146.     frame_params     fr_ps;
  147.     layer         info;
  148.     FILE        *musicout;    // decode to file
  149.     unsigned long     sample_frames;
  150.  
  151.     static int          i, j, k, stereo,
  152.              done = FALSE, clip, sync,
  153.              error_protection, crc_error_count,
  154.              total_error_count;
  155.     static unsigned int     old_crc, new_crc;
  156.     static unsigned int     bit_alloc[2][SBLIMIT],
  157.              scfsi[2][SBLIMIT],
  158.              scale_index[2][3][SBLIMIT];
  159.     unsigned long     bitsPerSlot, samplesPerFrame, frameNum = 0;
  160.     unsigned long     frameBits, gotBits = 0;
  161.     IFF_AIFF         pcm_aiff_data;
  162.     int             Max_gr;
  163.  
  164.     III_scalefac_t     III_scalefac;
  165.     III_side_info_t     III_side_info;
  166.  
  167. #ifdef    MACINTOSH
  168.     console_options.nrows = MAC_WINDOW_SIZE;
  169.     argc = ccommand(&argv);
  170. #endif
  171.  
  172.     /* Most large variables are declared dynamically to ensure
  173.        compatibility with smaller machines */
  174.  
  175.     pcm_sample = (PCM FAR *) mem_alloc((long) sizeof(PCM), "PCM Samp");
  176.     sample = (SAM FAR *) mem_alloc((long) sizeof(SAM), "Sample");
  177.     fraction = (FRA FAR *) mem_alloc((long) sizeof(FRA), "fraction");
  178.  
  179.     fr_ps.header = &info;
  180.     fr_ps.tab_num = -1;                /* no table loaded */
  181.     fr_ps.alloc = NULL;
  182.  
  183.     Arguments.topSb = 0;
  184.     Arguments.forkoff = 0;
  185.     GetArguments(argc, argv, &Arguments);
  186.  
  187.     if (Arguments.forkoff) {
  188.     switch (fork()) {
  189.     case 0:
  190.         break;    // child continues
  191.     case -1:
  192.         perror("fork");
  193.         exit(-1);
  194.         break;
  195.     default:
  196.         return 0;    // parent returns
  197.     }
  198.     }
  199.  
  200.     if (Arguments.write_to_file) {
  201.     if (strcmp(Arguments.decoded_file_name, "-") == 0)
  202.         musicout = stdout;
  203.     else {
  204.         if ((musicout = fopen(Arguments.decoded_file_name, "w+b")) == NULL) {
  205.         fprintf(stderr, "Could not create \"%s\".\n", Arguments.decoded_file_name);
  206.         exit(1);
  207.         }
  208.     }
  209.     }
  210. #if 0
  211.  else {
  212.     int    flag;
  213.  
  214.     // Open audio device write-only (to avoid buffering input data)
  215. /* FIXME:
  216.  * UGLY!!
  217.  */
  218.     if( (audiofd = open(
  219. #ifdef LINUX
  220.         "/dev/dsp",
  221. #else
  222.         "/dev/audio",
  223. #endif
  224.         O_WRONLY /*| O_NONBLOCK*/)) < 0 ) {
  225.         perror("open audio device");
  226.         exit(1);
  227.     }
  228.     }
  229. #endif
  230.  
  231.     open_bit_stream_r(&bs, Arguments.encoded_file_name, BUFFER_SIZE);
  232.  
  233.     if (Arguments.need_aiff)
  234.     if (aiff_seek_to_sound_data(musicout) == -1) {
  235.         if (strcmp(Arguments.decoded_file_name, "-") == 0)
  236.         fprintf(stderr, "Could not seek to PCM sound data in stdout\n");
  237.         else
  238.         fprintf(stderr, "Could not seek to PCM sound data in \"%s\"\n",
  239.             Arguments.decoded_file_name);
  240.         exit(1);
  241.     }
  242.  
  243.     sample_frames = 0;
  244.  
  245.     /* The output loop */
  246.     while (!end_bs(&bs)) {
  247.  
  248.     sync = seek_sync(&bs, SYNC_WORD, SYNC_WORD_LNGTH);
  249.     frameBits = sstell(&bs) - gotBits;
  250.     if (frameNum > 0)        /* don't want to print on 1st loop; no lay */
  251.         if(frameBits % bitsPerSlot)
  252.         fprintf(stderr, "Got %ld bits = %ld slots plus %ld\n",
  253.              frameBits, frameBits/bitsPerSlot, frameBits%bitsPerSlot);
  254.     gotBits += frameBits;
  255.  
  256.     if (!sync) {
  257.         if (Arguments.verbose) {
  258.         fprintf(stderr,
  259.             "\rFrame %d cannot be located, input stream may be empty\n",
  260.             frameNum);
  261.         }
  262.         done = TRUE;
  263.         /* Finally write out the buffer */
  264.         if (info.lay != 1)
  265.         out_fifo(*pcm_sample, 3, &fr_ps, done, musicout,
  266.                 &sample_frames);
  267.         else
  268.         out_fifo(*pcm_sample, 1, &fr_ps, done, musicout,
  269.                 &sample_frames);
  270.         break;
  271.     }
  272.  
  273.     decode_info(&bs, &fr_ps);
  274.     hdr_to_frps(&fr_ps);
  275.     stereo = fr_ps.stereo;
  276.     if (fr_ps.header->version == MPEG_PHASE2_LSF)
  277.         Max_gr = 1;
  278.     else
  279.         Max_gr = 2;
  280.  
  281.     error_protection = info.error_protection;
  282.     crc_error_count = 0;
  283.     total_error_count = 0;
  284.  
  285.     if (frameNum == 0) {
  286.         if (Arguments.verbose)
  287.         WriteHdr(&fr_ps, stderr);    /* printout layer/mode */
  288.  
  289.         if (!Arguments.write_to_file) {
  290.         init_sound(&info, stereo);
  291.         }
  292.     }
  293.  
  294. #ifdef ESPS
  295.     if (frameNum == 0 && Arguments.need_esps) {
  296.         esps_write_header(musicout,(long) sample_frames,
  297.         s_freq[info.version][info.sampling_frequency] * 1000,
  298.         (int) stereo, Arguments.decoded_file_name );
  299.     } /* MI */
  300. #endif
  301.  
  302.     if (frameNum % 10 == 0 && Arguments.verbose) {
  303.         fprintf(stderr, "\rFrame %-3lu ", frameNum);
  304.     }
  305.  
  306.     frameNum++;
  307.  
  308.     if (error_protection)
  309.         buffer_CRC(&bs, &old_crc);
  310.  
  311.     switch(info.lay) {
  312.     case 1:
  313.         bitsPerSlot = 32;
  314.         samplesPerFrame = 384;
  315.  
  316.         I_decode_bitalloc(&bs,bit_alloc,&fr_ps);
  317.         I_decode_scale(&bs, bit_alloc, scale_index, &fr_ps);
  318.  
  319.         if (error_protection) {
  320.         I_CRC_calc(&fr_ps, bit_alloc, &new_crc);
  321.         if (new_crc != old_crc) {
  322.             crc_error_count++;
  323.             total_error_count++;
  324.             recover_CRC_error(*pcm_sample, crc_error_count,
  325.                     &fr_ps, musicout, &sample_frames);
  326.             break;
  327.         }
  328.         else crc_error_count = 0;
  329.         }
  330.  
  331.         clip = 0;
  332.         for (i = 0; i < SCALE_BLOCK; i++) {
  333.         I_buffer_sample(&bs, (*sample), bit_alloc,&fr_ps);
  334.         I_dequantize_sample(*sample, *fraction, bit_alloc,&fr_ps);
  335.         I_denormalize_sample((*fraction),scale_index,&fr_ps);
  336.  
  337.         if (Arguments.topSb>0)         /* clear channels to 0 */
  338.            for (j=Arguments.topSb; j<fr_ps.sblimit; ++j)
  339.               for (k=0; k<stereo; ++k)
  340.              (*fraction)[k][0][j] = 0.0;
  341.  
  342.         for (j=0;j<stereo;j++) {
  343.            clip += SubBandSynthesis(&((*fraction)[j][0][0]), j,
  344.                          &((*pcm_sample)[j][0][0]));
  345.         }
  346.         out_fifo(*pcm_sample, 1, &fr_ps, done,
  347.              musicout, &sample_frames);
  348.          }
  349.          if (clip > 0 && Arguments.verbose)
  350.         fprintf(stderr, "\rFrame %-3lu: %d output samples clipped\n",
  351.                 frameNum - 1, clip);
  352.          break;
  353.  
  354.     case 2:
  355.         if (frameNum == 1) {
  356.         // Initialization code (original code calls this each loop)
  357.         bitsPerSlot = 8;
  358.         samplesPerFrame = 1152;
  359.         }
  360.         II_decode_bitalloc(&bs, bit_alloc, &fr_ps);
  361.         II_decode_scale(&bs, scfsi, bit_alloc, scale_index, &fr_ps);
  362.  
  363.         if (error_protection) { 
  364.         II_CRC_calc(&fr_ps, bit_alloc, scfsi, &new_crc);
  365.         if (new_crc != old_crc) {
  366.             crc_error_count++;
  367.             total_error_count++;
  368.             recover_CRC_error(*pcm_sample, crc_error_count,
  369.                 &fr_ps, musicout, &sample_frames);
  370.             break;
  371.         } else
  372.             crc_error_count = 0;
  373.          }
  374.  
  375.          clip = 0;
  376.          for (i = 0; i < SCALE_BLOCK; i++) {    // SCALE_BLOCK = 12
  377.         II_buffer_sample(&bs, (*sample), bit_alloc, &fr_ps);
  378.         II_dequantize_sample((*sample), bit_alloc, (*fraction), &fr_ps);
  379.         II_denormalize_sample((*fraction), scale_index, &fr_ps, i>>2);
  380. #ifdef DEBUG
  381.         if (Arguments.topSb > 0)      /* debug : clear channels to 0 */
  382.             for (j=Arguments.topSb; j<fr_ps.sblimit; ++j)
  383.             for (k=0; k<stereo; ++k)
  384.                 (*fraction)[k][0][j] =
  385.                 (*fraction)[k][1][j] =
  386.                 (*fraction)[k][2][j] = 0.0;
  387. #endif
  388.         for (j = 0; j < 3; j++) {
  389.             for (k = 0; k < stereo; k++) {
  390.             clip += SubBandSynthesis(&((*fraction)[k][j][0]),
  391.                 k, &((*pcm_sample)[k][j][0]));
  392.             }
  393.         }
  394.         out_fifo(*pcm_sample, 3, &fr_ps, done, musicout,
  395.              &sample_frames);
  396.          }
  397.          if (clip > 0 && Arguments.verbose)
  398.         fprintf(stderr, "\rFrame %-3lu: %d output samples clipped\n",
  399.                 frameNum - 1, clip);
  400.          break;
  401.  
  402.     case 3: {
  403.         static int    nSlots;
  404.         static int    gr, ch, ss, sb,
  405.             main_data_end, flush_main;
  406.         static int    bytes_to_discard;
  407.         static int    frame_start = 0;
  408.  
  409.         bitsPerSlot = 8;         
  410.         if (fr_ps.header->version == MPEG_PHASE2_LSF)
  411.         samplesPerFrame = 576;
  412.         else
  413.         samplesPerFrame = 1152;
  414.  
  415.         III_get_side_info(&bs, &III_side_info, &fr_ps);
  416.         nSlots = main_data_slots(fr_ps);
  417.  
  418.         for (; nSlots > 0; nSlots--)    // read main data
  419.         hputbuf((unsigned int) getbits(&bs,8), 8);
  420.         main_data_end = hsstell() / 8;    // of previous frame
  421.  
  422.         if (flush_main=(hsstell() % bitsPerSlot)) { 
  423.         hgetbits((int)(bitsPerSlot - flush_main));
  424.         main_data_end ++;
  425.         }
  426.         bytes_to_discard = frame_start - main_data_end -
  427.                    III_side_info.main_data_begin ;
  428.         if (main_data_end > 4096) {
  429.         frame_start -= 4096;
  430.         rewindNbytes(4096);
  431.         }
  432.  
  433.         frame_start += main_data_slots(fr_ps);
  434.         if (bytes_to_discard < 0) {
  435.         if (Arguments.verbose)
  436.             fprintf(stderr, "not enough main data to decode, "
  437.                  "frame discarded\n");
  438.         break;
  439.         }
  440.         for (; bytes_to_discard > 0; bytes_to_discard--)
  441.          hgetbits(8);
  442.  
  443.         clip = 0;
  444.         for (gr = 0; gr < Max_gr; gr++) {    // 1 or 2
  445.         static REAL    lr[2][SBLIMIT][SSLIMIT],
  446.                 ro[2][SBLIMIT][SSLIMIT];
  447.  
  448.         for (ch = 0; ch < stereo; ch++) {
  449.             // Quantized samples
  450.             static long int is[SBLIMIT][SSLIMIT];
  451.             int part2_start;
  452.  
  453.             part2_start = hsstell();
  454.             if (fr_ps.header->version != MPEG_PHASE2_LSF)
  455.             III_get_scale_factors(&III_scalefac,
  456.                 &III_side_info,    gr, ch, &fr_ps);
  457.             else
  458.             III_get_LSF_scale_factors(&III_scalefac,
  459.                 &III_side_info, gr,ch,&fr_ps);
  460.  
  461.             III_hufman_decode(is, &III_side_info, ch, gr, part2_start,
  462.                 &fr_ps);
  463.             III_dequantize_sample(is, ro[ch], &III_scalefac,
  464.                 &(III_side_info.ch[ch].gr[gr]), ch, &fr_ps);
  465.         }
  466.         III_stereo(ro, lr, &III_scalefac,
  467.                 &(III_side_info.ch[0].gr[gr]), &fr_ps);
  468.  
  469.         for (ch = 0; ch < stereo; ch++) {
  470.             static REAL re[SBLIMIT][SSLIMIT];
  471.             // Hybrid filter input
  472.             static REAL hybridIn[SBLIMIT][SSLIMIT];
  473.             // Hybrid filter out
  474.             static REAL hybridOut[SBLIMIT][SSLIMIT];
  475.             // PolyPhase Input
  476.             static REAL polyPhaseIn[SBLIMIT];
  477.  
  478.             III_reorder(lr[ch],re,&(III_side_info.ch[ch].gr[gr]),
  479.                   &fr_ps);
  480.  
  481.             III_antialias(re, hybridIn,        // antialias butterflies
  482.                   &(III_side_info.ch[ch].gr[gr]), &fr_ps);
  483.  
  484.             for (sb = 0; sb < SBLIMIT; sb++) {    // hybrid synthesis
  485.             III_hybrid(hybridIn[sb], hybridOut[sb], sb, ch,
  486.                    &(III_side_info.ch[ch].gr[gr]), &fr_ps);
  487.             }
  488.  
  489. #ifdef OPTIMIZE
  490.             for (ss = 0; ss < SSLIMIT; ss++) {    // Polyphase synthesis
  491.             for (sb = 0; sb < SBLIMIT; sb++) {
  492.                 // Perform frequency inversion for polyphase
  493.                 if ((ss % 2) && (sb % 2))
  494.                 polyPhaseIn[sb] = -hybridOut[sb][ss];
  495.                 else
  496.                 polyPhaseIn[sb] = hybridOut[sb][ss];
  497.             }
  498.             clip += SubBandSynthesis(polyPhaseIn, ch,
  499.                         &((*pcm_sample)[ch][ss][0]));
  500.             }
  501. #else
  502.             // Frequency inversion for polyphase
  503.             for (ss = 0; ss < SSLIMIT; ss++)        // 18
  504.             for (sb = 0; sb < SBLIMIT; sb++)    // 32
  505.                 if ((ss%2) && (sb%2))
  506.                 hybridOut[sb][ss] = -hybridOut[sb][ss];
  507.  
  508.             for (ss = 0; ss < SSLIMIT; ss++) {    // Polyphase synthesis
  509.             for (sb = 0; sb < SBLIMIT; sb++)
  510.                 polyPhaseIn[sb] = hybridOut[sb][ss];
  511.             clip += SubBandSynthesis (polyPhaseIn, ch,
  512.                         &((*pcm_sample)[ch][ss][0]));
  513.             }
  514. #endif    /* OPTIMIZE */
  515.         }
  516.         // Output PCM sample points for one granule
  517.         out_fifo(*pcm_sample, 18, &fr_ps, done, musicout,
  518.              &sample_frames);
  519.         }
  520.         if (clip > 0 && Arguments.verbose)
  521.         fprintf(stderr, "\rFrame %-3lu: %d output samples clipped\n",
  522.                 frameNum - 1, clip);
  523.  
  524.         } // end of layer 3 block
  525.         break;
  526.  
  527.     } // end of case
  528.  
  529. // Commented out for now
  530. #if 0
  531.     /* Skip ancillary data   HP 22-nov-95 */
  532.     if (info.bitrate_index > 0) { /* if not free-format */
  533.         long anc_len;
  534.  
  535.         anc_len = (int)((double)samplesPerFrame /
  536.                    s_freq[info.version][info.sampling_frequency] *
  537.                    (double)bitrate[info.version][info.lay-1][info.bitrate_index] /
  538.                    (double)bitsPerSlot);
  539.         if (info.padding)
  540.             anc_len++;
  541.         anc_len *= bitsPerSlot;
  542.         anc_len -= sstell(&bs)-gotBits+SYNC_WORD_LNGTH;
  543.         for (j=0; j<anc_len; j++)
  544.             get1bit(&bs);
  545.     }
  546. #endif
  547.  
  548.     }
  549.  
  550.     if (Arguments.need_aiff) {
  551.     pcm_aiff_data.numChannels    = stereo;
  552.     pcm_aiff_data.numSampleFrames    = sample_frames;
  553.     pcm_aiff_data.sampleSize    = 16;
  554.     pcm_aiff_data.sampleRate    = (double)
  555.         s_freq[info.version][info.sampling_frequency] * 1000;
  556.     pcm_aiff_data.sampleType    = IFF_ID_SSND;
  557.     pcm_aiff_data.blkAlgn.offset    = 0;
  558.     pcm_aiff_data.blkAlgn.blockSize = 0;
  559.  
  560.     if (aiff_write_headers(musicout, &pcm_aiff_data) == -1) {
  561.         if (strcmp(Arguments.decoded_file_name, "-") == 0)
  562.         fprintf(stderr, "Could not write AIFF headers to stdout\n",
  563.             Arguments.decoded_file_name);
  564.         else
  565.         fprintf(stderr, "Could not write AIFF headers to \"%s\"\n",
  566.             Arguments.decoded_file_name);
  567.         exit(2);
  568.     }
  569.     }
  570.  
  571.     if (Arguments.verbose)
  572.     fprintf(stderr, "\r%d frames, avg slots/frame = %.3f; b/smp = %.2f; br = %.3f kbps\n",
  573.         frameNum, (float) gotBits / (frameNum * bitsPerSlot),
  574.         (float) gotBits / (frameNum * samplesPerFrame),
  575.         (float) gotBits / (frameNum * samplesPerFrame) *
  576.         s_freq[info.version][info.sampling_frequency]);
  577.  
  578.     close_bit_stream_r(&bs);
  579.     if (Arguments.write_to_file)
  580.     fclose(musicout);
  581.     else
  582.     close(audiofd);
  583.  
  584.     /* for the correct AIFF header information */
  585.     /*             on the Macintosh            */
  586.     /* the file type and the file creator for  */
  587.     /* Macintosh compatible Digidesign is set  */
  588.  
  589. #ifdef  MACINTOSH
  590.     if (Arguments.need_aiff)
  591.         set_mac_file_attr(Arguments.decoded_file_name, VOL_REF_NUM,
  592.                                      CREATR_DEC_AIFF, FILTYP_DEC_AIFF);
  593.     else    set_mac_file_attr(Arguments.decoded_file_name, VOL_REF_NUM,
  594.                                      CREATR_DEC_BNRY, FILTYP_DEC_BNRY);
  595. #endif
  596.  
  597.     if (Arguments.verbose) {
  598.     fprintf(stderr, "Decoding of \"%s\" is finished\n",
  599.         Arguments.encoded_file_name);
  600.     if (Arguments.write_to_file) {
  601.         if (strcmp(Arguments.decoded_file_name, "-") == 0)
  602.         fprintf(stderr, "The decoded PCM output was written to stdout\n");
  603.         else
  604.         fprintf(stderr, "The decoded PCM output file name is \"%s\"\n",
  605.             Arguments.decoded_file_name);
  606.     }
  607.     }
  608.     return 0;
  609. }
  610.  
  611. static void usage(int level)    // print help info and exit
  612. {
  613.     if (level >= 1) {
  614.     fprintf(stderr,
  615.     "+---------------------------------------+\n"
  616.     "|   mpeg3play version 0.9.3, 2-Feb-97   |\n"
  617.     "+---------------------------------------+\n"
  618.     "This is an MPEG audio layer 2 and layer 3 decoder/player\n"
  619.     "based on public ISO/MPEG audio decoder source code. Solaris\n"
  620.     "port and optimizations by Johan.Hagman@mailbox.swipnet.se.\n\n"
  621.     "Copyright (C) 1996, 1997 by Johan Hagman.\n"
  622.     "This program is free software.\n\n");
  623.     }
  624. #ifdef DEBUG
  625.     fprintf(stderr, "usage: %s [-v] [-h] [-f] [-o outfile.aiff] [-s sb] filename\n",
  626.         programName);
  627. #else
  628.     fprintf(stderr, "usage: %s [-v] [-h] [-f] [-o outfile.aiff] filename\n",
  629.         programName);
  630. #endif
  631.     fprintf(stderr,"  -v          enable verbose mode\n");
  632.     fprintf(stderr,"  -h          display program help information\n");
  633.     fprintf(stderr,"  -f          fork off new player and return\n");
  634.     fprintf(stderr,"  -o outfile  write an AIFF output PCM sound file\n");
  635. #ifdef DEBUG
  636.     fprintf(stderr,"  -s sb       resynth only up to this subband (debugging)\n");
  637. #endif
  638.     fprintf(stderr,"  filename    bit stream of encoded audio (\"-\" means stdin)\n");
  639.     exit(1);
  640. }
  641.  
  642.  
  643. static void GetArguments(int argc, char **argv, Arguments_t *Arguments)
  644. {
  645.     char    t[50];
  646.     int        i = 0, err = 0;
  647.  
  648.     programName = "mpeg3play";
  649.  
  650.     Arguments->need_aiff = FALSE;
  651.     Arguments->need_esps = FALSE;    /* MI */
  652.     Arguments->write_to_file= FALSE;
  653.     Arguments->verbose = FALSE;
  654.  
  655.     Arguments->encoded_file_name[0] = '\0';
  656.     Arguments->decoded_file_name[0] = '\0';
  657.  
  658.     while (++i < argc && err == 0) {
  659.     char c, *token, *arg, *nextArg;
  660.     int  argUsed;
  661.  
  662.     token = argv[i];
  663.     // Original code was if (*token++ == '-'), this change makes
  664.     // it possible to use "-" for reading input stream from stdin
  665.     if (*token++ == '-' && *token != '\0') {
  666.         if (i+1 < argc)
  667.         nextArg = argv[i+1];
  668.         else
  669.         nextArg = "";
  670.         argUsed = 0;
  671.         while (c = *token++) {
  672.         if (*token /* NumericQ(token) */)
  673.             arg = token;
  674.         else
  675.             arg = nextArg;
  676.         switch(c) {
  677.         case 'v':
  678.             Arguments->verbose = TRUE;
  679.             break;
  680.         case 'h':
  681.             usage(1);
  682.             break;
  683.         case 'f':
  684.             Arguments->forkoff = TRUE;
  685.             break;
  686.         case 'o':
  687.             argUsed = 1;    // eat one arg
  688.             if (*arg == '\0') {
  689.             fprintf(stderr,"error: -o requires a filename arg\n");
  690.             err = 1;    // found no filename
  691.             } else {
  692.             strcpy(Arguments->decoded_file_name, arg);
  693.             Arguments->need_aiff = FALSE; //TRUE;
  694.             Arguments->write_to_file = TRUE;
  695.             }
  696.             break;
  697. #ifdef DEBUG
  698.         case 's':
  699.             Arguments->topSb = atoi(arg);
  700.             argUsed = 1;
  701.             if (Arguments->topSb<1 || Arguments->topSb>SBLIMIT) {
  702.             fprintf(stderr, "%s: -s band %s not %d..%d\n",
  703.                     programName, arg, 1, SBLIMIT);
  704.             err = 1;
  705.             }
  706.             break;
  707. #endif
  708.         default:
  709.             fprintf(stderr,"error: unrecognized option \"%c\"\n", c);
  710.             err = 1;
  711.             break;
  712.         }
  713.         if (argUsed) {
  714.             if (arg == token)
  715.             token = "";    /* no more from token */
  716.             else
  717.             ++i;        /* skip arg we used */
  718.             arg = "";
  719.             argUsed = 0;
  720.         }
  721.         } // end while
  722.  
  723.     } else { // end of options
  724.  
  725.         if (Arguments->encoded_file_name[0] == '\0') {
  726.         strcpy(Arguments->encoded_file_name, argv[i]);
  727.         } else {
  728.             fprintf(stderr, "error: excess arg \"%s\"\n", argv[i]);
  729.             err = 1;
  730.         }
  731.     }
  732.  
  733.     }
  734.  
  735.     if (err)
  736.     usage(0);
  737.     if (Arguments->encoded_file_name[0] == '\0') {
  738.         fprintf(stderr, "error: input file is missing\n");
  739.     usage(0);  /* never returns */
  740.     }
  741.  
  742.     if (Arguments->verbose && Arguments->need_aiff) {
  743.     if (strcmp(Arguments->decoded_file_name, "-") == 0)
  744.         fprintf(stderr, "The AIFF audio data is written to stdout\n");
  745.     else
  746.         fprintf(stderr, "The output file \"%s\" is written in AIFF format\n",
  747.             Arguments->decoded_file_name);
  748.     }
  749. }
  750.  
  751. /*
  752.  * Initialize audio device
  753. */
  754. static void init_sound(layer *info, int stereo) {
  755.     int samplefrq = (int)(s_freq[info->version][info->sampling_frequency] *
  756.               1000.0);
  757. #ifdef SOLARIS
  758.     audio_info_t    devinfo;
  759.  
  760.     // First pause and flush audio device
  761.     audio_pause(audiofd);
  762.     audio_flush(audiofd);
  763.  
  764.     AUDIO_INITINFO(&devinfo);
  765.  
  766.     devinfo.play.sample_rate = samplefrq;
  767.     devinfo.play.channels = stereo;
  768.     devinfo.play.precision = 16;
  769.     devinfo.play.encoding = AUDIO_ENCODING_LINEAR;
  770.     devinfo.play.buffer_size = 128 * 1024;
  771.  
  772.     if (ioctl(audiofd, AUDIO_SETINFO, &devinfo)) {
  773.     // Failed - retry with a smaller audio buffer
  774.     // Ultra1/Solaris 2.5 accepts no bigger than a 64K buffer
  775.     devinfo.play.buffer_size = 64 * 1024;
  776.     if (ioctl(audiofd, AUDIO_SETINFO, &devinfo)) {
  777.         perror("AUDIO_SETINFO");
  778.         exit(1);
  779.     } else {
  780.         smallAudioBuffer = 1;
  781.     }
  782.     }
  783.     audio_resume(audiofd);
  784.  
  785. #elif defined LINUX
  786.  
  787.     int tmp;
  788.  
  789.     /* sample size/precision? */
  790.     tmp = AFMT_S16_LE;
  791.     if (ioctl(audiofd, SNDCTL_DSP_SETFMT, &tmp) == -1) {
  792.     perror("SNDCTL_DSP_SETFMT");
  793.     exit(1);
  794.     }
  795.     /* mono/stereo */
  796.     tmp = stereo;
  797.     if (ioctl(audiofd, SNDCTL_DSP_CHANNELS, &tmp) == -1) {
  798.     perror("SNDCTL_DSP_CHANNELS");
  799.     exit(1);
  800.     }
  801.     /* frequency, this has to be set after the number of channels
  802.      * is selected otherwise SBPros fuck up. */
  803.     tmp = samplefrq;
  804.     if (ioctl(audiofd, SNDCTL_DSP_SPEED, &tmp) == -1) {
  805.     perror("SNDCTL_DSP_SPEED");
  806.     exit(1);
  807.     }
  808.  
  809. #elif defined HPUX
  810.  
  811.     if (ioctl(audiofd, AUDIO_SET_SAMPLE_RATE, samplefrq)) {
  812.     perror("AUDIO_SET_SAMPLE_RATE");
  813.     exit(1);
  814.     }
  815.     if (ioctl(audiofd, AUDIO_SET_CHANNELS, stereo)) {
  816.     perror("AUDIO_SET_CHANNELS");
  817.     exit(1);
  818.     }
  819.     if (ioctl(audiofd, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_LINEAR16BIT)) {
  820.     perror("AUDIO_SET_DATA_FORMAT");
  821.     exit(1);
  822.     }
  823.     if (ioctl(audiofd, AUDIO_SET_TXBUFSIZE, 128*1024)) {
  824.     perror("AUDIO_SET_TXBUFSIZE");
  825.     exit(1);
  826.     }
  827.  
  828. #else
  829. //#error "Check your compiler flags"
  830. #endif
  831. }
  832.