home *** CD-ROM | disk | FTP | other *** search
/ Windows 95 Secrets / Secrets2.iso / Audio / WAV / MaplayP / _SETUP.1 / maplay.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-06-25  |  9.9 KB  |  393 lines

  1. /* maplay.cpp - MPEG audio decoder
  2.  
  3.     Changes to original maplay 1.2, made by Jeff Tsay:
  4.  
  5.    - Header, bitstream, and miscellaneous flags come from main program
  6.    - CRC and range check violations ignored.
  7.    - Playtime not printed
  8.     - Before every frame, maplay checks if the user has asked it to
  9.      stop or seek, which will be reflected in the maplay_args. Every
  10.      16 frames a message is sent to the parent telling it which frame
  11.      maplay is decoding. All this stuff is synchronized using a mutex.
  12.    - Eliminated reading of crc from maplay_args.
  13.    - Layer III decoder object used for layer III frames. */
  14.  
  15. /*
  16.  *  @(#) maplay.cc 1.20, last edit: 6/22/94 12:32:55
  17.  *  @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
  18.  *  @(#) Berlin University of Technology
  19.  *
  20.  *  Many thanks for ideas and implementations to:
  21.  *  -> Jim Boucher (jboucher@flash.bu.edu)
  22.  *     for his idea and first implementation of 8 kHz u-law output
  23.  *  -> Louis P. Kruger (lpkruger@phoenix.princeton.edu)
  24.  *     for his implementation of the LinuxObuffer class
  25.  *
  26.  *  This program is free software; you can redistribute it and/or modify
  27.  *  it under the terms of the GNU General Public License as published by
  28.  *  the Free Software Foundation; either version 2 of the License, or
  29.  *  (at your option) any later version.
  30.  *
  31.  *  This program is distributed in the hope that it will be useful,
  32.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  33.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  34.  *  GNU General Public License for more details.
  35.  *
  36.  *  You should have received a copy of the GNU General Public License
  37.  *  along with this program; if not, write to the Free Software
  38.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  39.  */
  40.  
  41. /*
  42.  *  Changes from version 1.1 to 1.2:
  43.  *    - minor changes to create a LinuxObuffer object
  44.  *    - minor changes for a u-law version, which creates 8 kHz u-law output
  45.  *      on an amd device or in stdout mode, if compiled with ULAW defined
  46.  *    - option -amd forces maplay to treat /dev/audio as an amd device
  47.  *      in the u-law version. This is helpful on some SPARC clones.
  48.  *    - iostreams manipulator calls like "cerr << setw (2) << ..." replaced by
  49.  *      "cerr.width (2); ..." due to problems with older GNU C++ releases.
  50.  */
  51.  
  52.  
  53. #ifdef  __WIN32__
  54. #include "mp2win.h"
  55. #endif // __WIN32__
  56.  
  57. #ifndef  GUI
  58. #include <iostream.h>  // for reporting errors
  59. #endif   // GUI
  60.  
  61. #include "all.h"
  62. #include "crc.h"
  63. #include "header.h"
  64. #include "subband.h"
  65. #include "sublay1.h"
  66. #include "sublay2.h"
  67. #include "synfilt.h"
  68. #include "ibitstr.h"
  69. #include "obuffer.h"
  70. #include "args.h"
  71. #include "layer3.h"
  72.  
  73. #ifdef SEEK_STOP
  74. #include "mutx_imp.h"
  75. #endif
  76.  
  77. SynthesisFilter *filter1 = NULL, *filter2 = NULL;
  78. Obuffer *buffer = NULL;
  79. LayerIII_Decoder *l3decoder = NULL;
  80.  
  81. #pragma argsused
  82. void maplay_Exit(uint32 returncode)
  83. {
  84.  
  85. #ifdef SEEK_STOP
  86.   if ((returncode == 1) && buffer) {
  87.         buffer->set_stop_flag();
  88.   }
  89. #endif // SEEK_STOP
  90.  
  91.   delete buffer;
  92.   buffer = NULL;
  93.  
  94.   delete filter1;
  95.   filter1 = NULL;
  96.   delete filter2;
  97.   filter2 = NULL;
  98.  
  99.   delete l3decoder;
  100.   l3decoder = NULL;
  101. }
  102.  
  103. uint32 maplay(MPEG_Args *maplay_args)
  104. {
  105.     uint32 layer;
  106.     enum e_mode mode;
  107.  
  108.    bool read_ready = FALSE, write_ready = FALSE;
  109.  
  110.    // These arguments should not change while decoding
  111.     Crc16 *crc         = NULL;
  112.    Ibitstream *stream = maplay_args->stream;
  113.    Header *header     = maplay_args->MPEGheader;
  114.     enum e_channels which_channels = maplay_args->which_c;
  115.  
  116. #ifdef SEEK_STOP
  117.    _Mutex mutex       = maplay_args->mutex;
  118. #endif
  119.  
  120. #ifdef WIN32GUI
  121.    HWND hWnd          = maplay_args->hWnd;
  122. #else
  123.     // copy your operating system dependent arguments here
  124. #endif // WIN32GUI
  125.  
  126.    // get info from header of first frame:
  127.    layer = header->layer();
  128.    if ((mode = header->mode()) == single_channel)
  129.        which_channels = left;
  130.  
  131.    // create filter(s):
  132.    {
  133.       real scalefactor = (maplay_args->use_own_scalefactor) ?
  134.                               maplay_args->scalefactor  :
  135.                          32768.0f;
  136.  
  137.         filter1 = new SynthesisFilter(0, scalefactor);
  138.  
  139.        if ((mode != single_channel) && (which_channels == both))
  140.            filter2 = new SynthesisFilter(1, scalefactor);
  141.    }
  142.  
  143.    // create buffer, and check to see if created ok:
  144.  
  145. #ifdef __WIN32__
  146.  
  147.     if (maplay_args->stdout_mode) {
  148.  
  149.        buffer = create_stdout_obuffer(maplay_args);
  150.  
  151.    } else {
  152.  
  153.      switch (maplay_args->output_mode) {
  154.  
  155.       case O_WAVEMAPPER:
  156.       case O_DIRECTSOUND:
  157.       buffer = create_obuffer(maplay_args);
  158.       break;
  159.  
  160.       case O_WAVEFILE:
  161.       buffer = create_Wavefile_obuffer(maplay_args);
  162.       break;
  163.      }
  164.    }
  165.  
  166. #else
  167.  
  168.    buffer = (maplay_args->stdout_mode) ?
  169.                create_stdout_obuffer(maplay_args) :
  170.                create_obuffer(maplay_args);
  171.  
  172. #endif
  173.  
  174.    if (buffer == NULL) {
  175.         maplay_Exit(0);
  176.       return(1);
  177.    }
  178.  
  179.   // Layer III : initialize decoder
  180.  
  181.       if (layer == 3)
  182.       l3decoder = new LayerIII_Decoder(stream, header, filter1,
  183.                                                   filter2, buffer, which_channels);
  184.  
  185.    do
  186.    {
  187.  
  188. #ifdef SEEK_STOP
  189.  
  190.      mtx_lock(mutex);
  191.  
  192.      if (maplay_args->stop) {
  193.       maplay_Exit(1);
  194.       mtx_unlock(mutex);
  195.       return(0);
  196.     }
  197.  
  198.      if (maplay_args->position_change) {
  199.  
  200.         buffer->clear_buffer();
  201.  
  202.       if (!header->stream_seek(stream, maplay_args->desired_position)) {
  203.           maplay_Exit(0);
  204.           mtx_unlock(mutex);
  205.          return(1);
  206.       }
  207.  
  208.         maplay_args->position_change = FALSE;
  209.  
  210.       filter1->reset();
  211.  
  212.       if ((which_channels == both) && (mode != single_channel))
  213.           filter2->reset();
  214.  
  215.       if (l3decoder)
  216.             l3decoder->seek_notify();
  217.  
  218.         // notify the parent of the current position
  219.  
  220. #ifdef WIN32GUI
  221.         PostMessage(hWnd, SEEK_ACK, NULL, NULL);
  222.         PostMessage(hWnd, SCROLL_POS, stream->current_frame(), 0);
  223. #else
  224.  
  225. #endif // WIN32GUI
  226.  
  227.      }
  228.  
  229.      // Send notification to the scroll bar every 16 frames
  230.     {
  231.       int32 cf = stream->current_frame();
  232.       if (!(cf & 0xf) && !(maplay_args->stop)) {
  233.         // Notify the parent of the current position
  234.  
  235. #ifdef WIN32GUI
  236.                PostMessage(hWnd, SCROLL_POS, cf, 0);
  237. #else
  238.  
  239. #endif // WIN32GUI
  240.       }
  241.  
  242.     mtx_unlock(mutex);
  243.     }
  244.  
  245. #endif // SEEK_STOP
  246.  
  247.      // is there a change in important parameters?
  248.      // (bitrate switching is allowed)
  249.      if (header->layer() != layer)
  250.      {
  251.         // layer switching is allowed
  252.  
  253.       if (header->layer() == 3) {
  254.          l3decoder = new LayerIII_Decoder(stream, header,
  255.                                                        filter1, filter2,
  256.                                           buffer, which_channels);
  257.       } else if (layer == 3) {
  258.           delete l3decoder;
  259.          l3decoder = NULL;
  260.       }
  261.  
  262.         layer = header->layer();
  263.      }
  264.  
  265.      if (layer != 3) {
  266.  
  267.         Subband *subbands[32];
  268.         uint32 num_subbands = header->number_of_subbands();
  269.        uint32 i;
  270.        mode = header->mode();
  271.  
  272.          // create subband objects:
  273.          if (layer == 1)
  274.          {
  275.             if (mode == single_channel)
  276.                 for (i = 0; i < num_subbands; ++i)
  277.                   subbands[i] = new SubbandLayer1(i);
  278.             else if (mode == joint_stereo) {
  279.                 for (i = 0; i < header->intensity_stereo_bound(); ++i)
  280.                   subbands[i] = new SubbandLayer1Stereo(i);
  281.                 for (; i < num_subbands; ++i)
  282.                   subbands[i] = new SubbandLayer1IntensityStereo(i);
  283.             } else {
  284.                 for (i = 0; i < num_subbands; ++i)
  285.                   subbands[i] = new SubbandLayer1Stereo(i);
  286.           }
  287.  
  288.          } else { // Layer II
  289.             if (mode == single_channel)
  290.                 for (i = 0; i < num_subbands; ++i)
  291.                  subbands[i] = new SubbandLayer2(i);
  292.             else if (mode == joint_stereo)
  293.             {
  294.                 for (i = 0; i < header->intensity_stereo_bound(); ++i)
  295.                      subbands[i] = new SubbandLayer2Stereo(i);
  296.                 for (; i < num_subbands; ++i)
  297.                     subbands[i] = new SubbandLayer2IntensityStereo(i);
  298.             } else {
  299.                 for (i = 0; i < num_subbands; ++i)
  300.                     subbands[i] = new SubbandLayer2Stereo(i);
  301.          }
  302.           }
  303.  
  304.           // start to read audio data:
  305.         for (i = 0; i < num_subbands; ++i)
  306.            subbands[i]->read_allocation(stream, header, crc);
  307.  
  308.          if (layer == 2)
  309.             for (i = 0; i < num_subbands; ++i)
  310.                 ((SubbandLayer2 *)subbands[i])->read_scalefactor_selection(stream,
  311.                                                                                          crc);
  312.  
  313.          if (!crc || header->checksum_ok())
  314.          {
  315.             // no checksums or checksum ok, continue reading from stream:
  316.             for (i = 0; i < num_subbands; ++i)
  317.                 subbands[i]->read_scalefactor(stream, header);
  318.  
  319.             do
  320.             {
  321.                 for (i = 0; i < num_subbands; ++i)
  322.                     read_ready = subbands[i]->read_sampledata(stream);
  323.  
  324.                 do
  325.                 {
  326.                     for (i = 0; i < num_subbands; ++i)
  327.                         write_ready = subbands[i]->put_next_sample(which_channels,
  328.                                                               filter1, filter2);
  329.  
  330.                     filter1->calculate_pcm_samples(buffer);
  331.                     if ((which_channels == both) && (mode != single_channel))
  332.                    filter2->calculate_pcm_samples(buffer);
  333.                 } while (!write_ready);
  334.             } while (!read_ready);
  335.  
  336.           buffer->write_buffer(1);
  337.  
  338.          } // checksum ok
  339.      // Jeff : Don't let user know if crc violated.
  340. //        else
  341.         // Sh*t! Wrong crc checksum in frame!
  342. //        cerr << "WARNING: frame contains wrong crc checksum! (throwing frame away)\n";
  343.  
  344.        for (i = 0; i < num_subbands; ++i)
  345.             delete subbands[i];
  346.  
  347.     } else {  // Layer III
  348.        l3decoder->decode();
  349.     }
  350.  
  351.    }
  352.    while (header->read_header(stream, &crc));
  353.  
  354. #ifdef SEEK_STOP
  355.  
  356.    mtx_lock(mutex);
  357.  
  358.    if (!maplay_args->stop) {
  359.  
  360.       // notify the parent of the last frame
  361.  
  362. #ifdef WIN32GUI
  363.       PostMessage(hWnd, SCROLL_POS, stream->current_frame(), 0);
  364. #else
  365.  
  366. #endif // WIN32GUI
  367.     }
  368.  
  369. #endif // SEEK_STOP
  370.  
  371.    maplay_Exit(0);
  372.  
  373. #ifdef SEEK_STOP
  374.    maplay_args->done = TRUE;
  375.  
  376.    if (!maplay_args->stop) {
  377.  
  378.      // tell the parent that we are done
  379.  
  380. #ifdef WIN32GUI
  381.         PostMessage(hWnd, WM_THREADEND, NULL, NULL);
  382. #else
  383.  
  384. #endif // WIN32GUI
  385.     }
  386.  
  387.    mtx_unlock(mutex);
  388.  
  389. #endif // SEEK_STOP
  390.  
  391.    return(0);
  392. }
  393.