home *** CD-ROM | disk | FTP | other *** search
/ PC Shareware 1997 June / PC_Shareware-1997-06.iso / manga / mp2win95 / _setup.1 / MAPLAY.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-01  |  11.4 KB  |  407 lines

  1. /* Adapted to Win32 version by Jeff Tsay. Differences: This is a thread
  2.     of the the main program, which is the interface. Header, bitstream, and
  3.     CRC come from the main program. Minimal error checking.
  4.     CRC and range check violations ignored. Playtime not printed. Buffers
  5.     initialized differently. Most global variables have been replaced with
  6.     local ones. Last edit 3/09/96. */
  7.  
  8. /* Version 1.80 changes: (last edit : 01/31/97)
  9.  
  10.     Before every frame, maplay check if the user has asked it to
  11.    stop or seek.
  12.    which will be reflected in the maplay_args.
  13.  
  14.    Eliminated reading of crc from maplay_args.
  15.  
  16.    Layer III decoder object used for layer III frames. */
  17.  
  18.  
  19. /*
  20.  *  @(#) maplay.cc 1.20, last edit: 6/22/94 12:32:55
  21.  *  @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
  22.  *  @(#) Berlin University of Technology
  23.  *
  24.  *  Many thanks for ideas and implementations to:
  25.  *  -> Jim Boucher (jboucher@flash.bu.edu)
  26.  *     for his idea and first implementation of 8 kHz u-law output
  27.  *  -> Louis P. Kruger (lpkruger@phoenix.princeton.edu)
  28.  *     for his implementation of the LinuxObuffer class
  29.  *
  30.  *  This program is free software; you can redistribute it and/or modify
  31.  *  it under the terms of the GNU General Public License as published by
  32.  *  the Free Software Foundation; either version 2 of the License, or
  33.  *  (at your option) any later version.
  34.  *
  35.  *  This program is distributed in the hope that it will be useful,
  36.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  37.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  38.  *  GNU General Public License for more details.
  39.  *
  40.  *  You should have received a copy of the GNU General Public License
  41.  *  along with this program; if not, write to the Free Software
  42.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  43.  */
  44.  
  45. /*
  46.  *  Changes from version 1.1 to 1.2:
  47.  *    - minor changes to create a LinuxObuffer object
  48.  *    - minor changes for a u-law version, which creates 8 kHz u-law output
  49.  *      on an amd device or in stdout mode, if compiled with ULAW defined
  50.  *    - option -amd forces maplay to treat /dev/audio as an amd device
  51.  *      in the u-law version. This is helpful on some SPARC clones.
  52.  *    - iostreams manipulator calls like "cerr << setw (2) << ..." replaced by
  53.  *      "cerr.width (2); ..." due to problems with older GNU C++ releases.
  54.  */
  55.  
  56.  
  57. #define STRICT
  58. #define WIN32_LEAN_AND_MEAN
  59. #define NOMCX
  60. #define NOIME
  61. // #define NOGDI             GDI APIs and definitions
  62. // #define NOUSER            USER APIs and definitions
  63. #define NOSOUND
  64. #define NOCOMM
  65. #define NODRIVERS
  66. #define OEMRESOURCE
  67. #define NONLS
  68. #define NOSERVICE
  69. #define NOKANJI
  70. #define NOMINMAX
  71. #define NOLOGERROR
  72. #define NOPROFILER
  73. #define NOMEMMGR
  74. #define NOLFILEIO
  75. #define NOOPENFILE
  76. #define NORESOURCE
  77. #define NOATOM
  78. #define NOLANGUAGE
  79. #define NOLSTRING
  80. #define NODBCS
  81. #define NOKEYBOARDINFO
  82. #define NOGDICAPMASKS
  83. #define NOCOLOR
  84. #define NOGDIOBJ
  85. #define NODRAWTEXT
  86. #define NOTEXTMETRIC
  87. #define NOSCALABLEFONT
  88. #define NOBITMAP
  89. #define NORASTEROPS
  90. #define NOMETAFILE
  91. #define NOSYSMETRICS
  92. #define NOSYSTEMPARAMSINFO
  93. #define NOMSG
  94. #define NOWINSTYLES
  95. #define NOWINOFFSETS
  96. #define NOSHOWWINDOW
  97. #define NODEFERWINDOWPOS
  98. #define NOVIRTUALKEYCODES
  99. #define NOKEYSTATES
  100. #define NOWH
  101. #define NOMENUS
  102. #define NOSCROLL
  103. #define NOCLIPBOARD
  104. // #define NOICONS
  105. // #define NOMB
  106. #define NOSYSCOMMANDS
  107. #define NOMDI
  108. #define NOCTLMGR
  109. #define NOWINMESSAGES
  110. #define NOHELP
  111. // #define _WINUSER_
  112. #define __oleidl_h__
  113. #define _OLE2_H_
  114. #include <windows.h>
  115.  
  116. #define MMNODRV
  117. #define MMNOSOUND
  118. #define MMNOMIDI
  119. #define MMNOAUX
  120. #define MMNOTIMER
  121. #define MMNOJOY
  122. #define MMNOMCI
  123. #define MMNOMMIO
  124. #define MMNOMMSYSTEM
  125. #include <mmsystem.h>
  126. #include "all.h"
  127. #include "crc.h"
  128. #include "header.h"
  129. #include "subband.h"
  130. #include "sublay1.h"
  131. #include "sublay2.h"
  132. #include "synfilt.h"
  133. #include "ibitstr.h"
  134. #include "obuffer.h"
  135. #include "args.h"
  136. #include "bit_res.h"
  137. #include "scalfact.h"
  138. #include "l3type.h"
  139. #include "layer3.h"
  140. #include "mp2win.h"
  141.  
  142. // data extracted from commandline arguments:
  143.  
  144. SynthesisFilter *filter1 = NULL, *filter2 = NULL;
  145. Obuffer *buffer = NULL;
  146. Header *header = NULL;
  147. Subband *subbands[32] = {NULL, NULL, NULL, NULL,
  148.                                  NULL, NULL, NULL, NULL,
  149.                          NULL, NULL, NULL, NULL,
  150.                          NULL, NULL, NULL, NULL,
  151.                          NULL, NULL, NULL, NULL,
  152.                          NULL, NULL, NULL, NULL,
  153.                          NULL, NULL, NULL, NULL,
  154.                          NULL, NULL, NULL, NULL};
  155.  
  156. LayerIII_Decoder *l3decoder = NULL;
  157.  
  158. DWORD maplay_Exit (DWORD returncode)
  159. {
  160.   if ((returncode == 1) && buffer) {
  161.         buffer->set_stop_flag();
  162.   }
  163.  
  164.   delete buffer;
  165.   buffer = NULL;
  166.  
  167.   delete filter1;
  168.   filter1 = NULL;
  169.   delete filter2;
  170.   filter2 = NULL;
  171.  
  172.   delete l3decoder;
  173.   l3decoder = NULL;
  174.  
  175.   return(0L);
  176. }
  177.  
  178. DWORD maplay (MPEG_Args *maplay_args)
  179. {
  180.  
  181.     enum e_channels which_channels = maplay_args->which_c;
  182.  
  183.     uint32 layer;
  184.     e_mode mode;
  185.     e_sample_frequency sample_frequency;
  186.  
  187.    int32 i;
  188.    BOOL read_ready = FALSE, write_ready = FALSE;
  189.  
  190.     Crc16 *crc = NULL;
  191.    Ibitstream *stream = maplay_args->stream;
  192.    header = maplay_args->MPEGheader;
  193.    HWND hWnd = maplay_args->hWnd;
  194.    HWAVEOUT *phwo = maplay_args->phwo;
  195.    char *huffdec_path = maplay_args->huffdec_path;
  196.  
  197.    // get info from header of first frame:
  198.    layer = header->layer ();
  199.    if ((mode = header->mode ()) == single_channel)
  200.        which_channels = left;
  201.    sample_frequency = header->sample_frequency ();
  202.  
  203.    // create filter(s):
  204.     filter1 = new SynthesisFilter (0);
  205.  
  206.    if (mode != single_channel && which_channels == both)
  207.        filter2 = new SynthesisFilter (1);
  208.  
  209.    // create buffer:
  210.  
  211.     if (mode == single_channel || which_channels != both)
  212.         buffer = new MCIbuffer (1, header, phwo);    // mono
  213.    else
  214.         buffer = new MCIbuffer (2, header, phwo);    // stereo
  215.  
  216.   // Layer III : initialize decoder
  217.  
  218.       if (layer == 3) {
  219.  
  220.        if (mode == single_channel)
  221.            l3decoder = new LayerIII_Decoder(huffdec_path, stream, header, filter1,
  222.                                                       NULL, buffer);
  223.       else
  224.          l3decoder = new LayerIII_Decoder(huffdec_path, stream, header, filter1,
  225.                                                       filter2, buffer);
  226.    }
  227.  
  228.    do
  229.    {
  230.  
  231.     if (maplay_args->stop_query()) {
  232.       maplay_Exit(1L);
  233.       return(0);
  234.     }
  235.  
  236.      if (maplay_args->position_change_query()) {
  237.  
  238.         buffer->clear_buffer();
  239.  
  240.         if (header->sample_frequency() != fourtyfour_point_one)
  241.             stream->seek(maplay_args->desired_position_query(),
  242.                          header->calculate_framesize());
  243.         else
  244.             stream->seek_pad(maplay_args->desired_position_query(),
  245.                          header->calculate_framesize() - header->padding());
  246.  
  247.         maplay_args->set_position_change(FALSE);
  248.  
  249.         if (!header->read_header (stream, &crc))
  250.             goto quit;
  251.  
  252.       if (l3decoder)
  253.           l3decoder->seek_notify();
  254.  
  255.         SendMessage(hWnd, SEEK_ACK, NULL, NULL);
  256.         SendMessage(hWnd, SCROLL_POS, stream->current_frame, 0);
  257.      }
  258.  
  259.      // is there a change in important parameters?
  260.      // (bitrate switching is allowed)
  261.      if (header->layer () != layer)
  262.      {
  263.         // layer switching is allowed
  264.  
  265.       if (header->layer() == 3) {
  266.  
  267.            if (mode == single_channel)
  268.                l3decoder = new LayerIII_Decoder(huffdec_path, stream, header,
  269.                                                         filter1, NULL, buffer);
  270.           else
  271.              l3decoder = new LayerIII_Decoder(huffdec_path, stream, header,
  272.                                                         filter1, filter2, buffer);
  273.  
  274.       } else if (layer == 3) {
  275.           delete l3decoder;
  276.          l3decoder = NULL;
  277.       }
  278.  
  279.         layer = header->layer ();
  280.      }
  281.      if ((mode == single_channel && header->mode () != single_channel) ||
  282.     (mode != single_channel && header->mode () == single_channel))
  283.      {
  284.         MessageBox(hWnd,"Illegal switch from single channel to stereo \
  285. or vice versa.", "Decoding Error", MB_ICONEXCLAMATION);
  286.         maplay_Exit (0L);
  287.       ExitThread(1L);
  288.      }
  289.      if (header->sample_frequency () != sample_frequency)
  290.      {
  291.         MessageBox(hWnd, "Sorry, can't switch the sample frequency in the \
  292. middle of the stream.", "Decoding Error", MB_ICONEXCLAMATION);
  293.         maplay_Exit (0L);
  294.       ExitThread(1L);
  295.       return(0L);
  296.      }
  297.  
  298.     if (header->layer() != 3) {
  299.  
  300.      // create subband objects:
  301.      if (header->layer () == 1)
  302.      {
  303.         if (header->mode () == single_channel)
  304.     for (i = 0; i < header->number_of_subbands (); ++i)
  305.       subbands[i] = new SubbandLayer1 (i);
  306.         else if (header->mode () == joint_stereo)
  307.         {
  308.     for (i = 0; i < header->intensity_stereo_bound (); ++i)
  309.       subbands[i] = new SubbandLayer1Stereo (i);
  310.     for (; i < header->number_of_subbands (); ++i)
  311.       subbands[i] = new SubbandLayer1IntensityStereo (i);
  312.         }
  313.         else
  314.     for (i = 0; i < header->number_of_subbands (); ++i)
  315.       subbands[i] = new SubbandLayer1Stereo (i);
  316.      }
  317.      else if (header->layer () == 2)
  318.      {
  319.         if (header->mode () == single_channel)
  320.     for (i = 0; i < header->number_of_subbands (); ++i)
  321.       subbands[i] = new SubbandLayer2 (i);
  322.         else if (header->mode () == joint_stereo)
  323.         {
  324.     for (i = 0; i < header->intensity_stereo_bound (); ++i)
  325.       subbands[i] = new SubbandLayer2Stereo (i);
  326.     for (; i < header->number_of_subbands (); ++i)
  327.       subbands[i] = new SubbandLayer2IntensityStereo (i);
  328.         }
  329.         else
  330.     for (i = 0; i < header->number_of_subbands (); ++i)
  331.       subbands[i] = new SubbandLayer2Stereo (i);
  332.      }
  333.  
  334.      // start to read audio data:
  335.      for (i = 0; i < header->number_of_subbands (); ++i)
  336.         subbands[i]->read_allocation (stream, header, crc);
  337.  
  338.      if (header->layer () == 2)
  339.         for (i = 0; i < header->number_of_subbands (); ++i)
  340.     ((SubbandLayer2 *)subbands[i])->read_scalefactor_selection (stream, crc);
  341.  
  342.      if (!crc || header->checksum_ok ())
  343.      {
  344.         // no checksums or checksum ok, continue reading from stream:
  345.         for (i = 0; i < header->number_of_subbands (); ++i)
  346.     subbands[i]->read_scalefactor (stream, header);
  347.  
  348.         do
  349.         {
  350.             for (i = 0; i < header->number_of_subbands (); ++i)
  351.                 read_ready = subbands[i]->read_sampledata (stream);
  352.  
  353.             do
  354.             {
  355.                 for (i = 0; i < header->number_of_subbands (); ++i)
  356.                     write_ready = subbands[i]->put_next_sample (which_channels,
  357.                                                                               filter1, filter2);
  358.  
  359.                 filter1->calculate_pcm_samples (buffer);
  360.                 if (which_channels == both && header->mode () != single_channel)
  361.                      filter2->calculate_pcm_samples (buffer);
  362.             } while (!write_ready);
  363.         } while (!read_ready);
  364.  
  365.         buffer->write_buffer (1);        // write to stdout
  366.      }
  367.      // Jeff : Don't let user know if crc violated.
  368. //     else
  369.         // Sh*t! Wrong crc checksum in frame!
  370. //        cerr << "WARNING: frame contains wrong crc checksum! (throwing frame away)\n";
  371.      for (i = 0; i < header->number_of_subbands (); ++i) {
  372.         delete subbands[i];
  373.       subbands[i] = NULL;
  374.     }
  375.  
  376.    } else {  // Layer III
  377.        l3decoder->decode();
  378.    }
  379.  
  380.      // Send notification to the scroll bar every 16 frames
  381.      if (!(stream->current_frame & 0xf) &&  (!maplay_args->stop_query()))
  382.          SendMessage(hWnd, SCROLL_POS, stream->current_frame, 0);
  383.  
  384.   }
  385.   while (header->read_header (stream, &crc));
  386.  
  387.   quit:
  388.   // Saturate the scroll bar
  389.   if (!maplay_args->stop_query())
  390.       SendMessage(hWnd, SCROLL_POS, stream->current_frame, 0);
  391.  
  392.   delete buffer;
  393.   buffer = NULL;
  394.  
  395.   delete filter1;
  396.   filter1 = NULL;
  397.   delete filter2;
  398.   filter2 = NULL;
  399.  
  400.   delete l3decoder;
  401.   l3decoder = NULL;
  402.  
  403.   maplay_args->set_done(TRUE);
  404.   SendMessage(hWnd, WM_THREADEND, NULL, NULL);
  405.   return(0);
  406. }
  407.