home *** CD-ROM | disk | FTP | other *** search
/ The Best of Windows 95.com 1996 September / WIN95_09964.iso / sound / mpw32-5s.zip / IBITSTR.CPP < prev    next >
C/C++ Source or Header  |  1996-07-26  |  9KB  |  330 lines

  1.  
  2. /*
  3.  *  @(#) ibitstream.cc 1.8, last edit: 6/15/94 16:51:45
  4.  *  @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
  5.  *  @(#) Berlin University of Technology
  6.  *
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License
  18.  *  along with this program; if not, write to the Free Software
  19.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  */
  21.  
  22. /*
  23.  *  Changes from version 1.1 to 1.2:
  24.  *    - third argument in open syscall added
  25.  *    - minor bug in get_header() fixed
  26.  */
  27.  
  28. /* Modified for Windows file handles by Jeff Tsay. Last edit 1/26/96. */
  29.  
  30. #define STRICT
  31. #define WIN32_LEAN_AND_MEAN
  32. #define NOMCX
  33. #define NOIME
  34. // #define NOGDI
  35. // #define NOUSER
  36. #define NOSOUND
  37. #define NOCOMM
  38. #define NODRIVERS
  39. #define OEMRESOURCE
  40. #define NONLS
  41. #define NOSERVICE
  42. #define NOKANJI
  43. #define NOMINMAX
  44. #define NOLOGERROR
  45. #define NOPROFILER
  46. #define NOMEMMGR
  47. #define NOLFILEIO
  48. #define NOOPENFILE
  49. #define NORESOURCE
  50. #define NOATOM
  51. #define NOLANGUAGE
  52. #define NOLSTRING
  53. #define NODBCS
  54. #define NOKEYBOARDINFO
  55. #define NOGDICAPMASKS
  56. #define NOCOLOR
  57. #define NOGDIOBJ
  58. #define NODRAWTEXT
  59. #define NOTEXTMETRIC
  60. #define NOSCALABLEFONT
  61. #define NOBITMAP
  62. #define NORASTEROPS
  63. #define NOMETAFILE
  64. #define NOSYSMETRICS
  65. #define NOSYSTEMPARAMSINFO
  66. #define NOMSG
  67. #define NOWINSTYLES
  68. #define NOWINOFFSETS
  69. #define NOSHOWWINDOW
  70. #define NODEFERWINDOWPOS
  71. #define NOVIRTUALKEYCODES
  72. #define NOKEYSTATES
  73. #define NOWH
  74. #define NOMENUS
  75. #define NOSCROLL
  76. #define NOCLIPBOARD
  77. #define NOICONS
  78. // #define NOMB
  79. #define NOSYSCOMMANDS
  80. #define NOMDI
  81. #define NOCTLMGR
  82. #define NOWINMESSAGES
  83. #define NOHELP
  84. // #define _WINUSER_
  85. #define __oleidl_h__
  86. #define _OLE2_H_
  87. #include <windows.h>
  88.  
  89. #include "all.h"
  90. #include "ibitstr.h"
  91. #include "header.h"
  92. #include "l3type.h"
  93.  
  94. #define swap_int32(int_32) (((int_32) << 24) | (((int_32) << 8) & 0x00ff0000) | \
  95.                 (((int_32) >> 8) & 0x0000ff00) | ((int_32) >> 24))
  96.  
  97. Ibitstream::Ibitstream (const char *filename, HWND hWnd0)        // constructor
  98. {
  99.  
  100.   hWnd=hWnd0;
  101.  
  102.   security.nLength=sizeof(SECURITY_ATTRIBUTES);
  103.   security.lpSecurityDescriptor=NULL;
  104.   security.bInheritHandle=FALSE;
  105.  
  106.   FH=CreateFile(filename, GENERIC_READ, FILE_SHARE_READ,
  107.                      &security, OPEN_EXISTING, NULL, NULL);
  108.  
  109.   if (FH==INVALID_HANDLE_VALUE) {
  110.     char *bad_file_msg=new char[256];
  111.     lstrcpy(bad_file_msg, "Error opening file: ");
  112.     MessageBox(hWnd, strcat(bad_file_msg, filename) , "Invalid handle", MB_OK);
  113.     delete bad_file_msg;
  114.   }
  115.  
  116.   wordpointer = buffer;
  117.   bitindex = 0;
  118.  
  119.   // Seeking variables
  120.   offset = NULL;
  121.   current_frame = -1;
  122.   last_frame_number = -1;
  123. }
  124.  
  125. Ibitstream::~Ibitstream (void)                // destructor
  126. {
  127.   delete offset;
  128.   CloseHandle(FH);
  129. }
  130.  
  131. BOOL Ibitstream::get_header (uint32 *headerstring)
  132. {
  133.   BOOL result;
  134.   DWORD numread;
  135.   result=(BOOL)  ReadFile(FH, (char*)headerstring, 4, &numread, NULL);
  136.  
  137.   register uint32 header = *headerstring;
  138.   *headerstring = swap_int32 (header);
  139.  
  140.   if (last_frame_number < ++current_frame)
  141.     last_frame_number = current_frame;
  142.  
  143.   return ((BOOL) (result && (numread==4)));
  144. }
  145.  
  146. BOOL Ibitstream::read_frame (uint32 bytesize)
  147. {
  148.  
  149.     DWORD numread;
  150.     BOOL result=ReadFile(FH, buffer, bytesize, &numread, NULL);
  151.  
  152. /*  if (bytesize > (bufferintsize << 2))
  153.   {
  154.      cerr << "Internal error: framelength > bufferlength?!\n";
  155.      exit (1);
  156.   } */
  157.  
  158.   wordpointer = buffer;
  159.   bitindex = 0;
  160.   framesize = bytesize;
  161. // #ifdef DAMN_INTEL_BYTE_ORDER
  162.   register uint32 *wordp, word;
  163.   for (wordp = buffer + ((bytesize - 1) >> 2); wordp >= buffer; --wordp)
  164.   {
  165.      word = *wordp;
  166.      *wordp = swap_int32 (word);
  167.   }
  168. // #endif
  169.  
  170.   return ((BOOL) (result && (numread==framesize)));
  171. }
  172.  
  173. uint32 Ibitstream::get_bits (uint32 number_of_bits)
  174. {
  175.   static uint32 bitmask[17] =
  176.   {
  177.      0,    // dummy
  178.      0x00000001, 0x00000003, 0x00000007, 0x0000000F,
  179.      0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
  180.      0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
  181.      0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF
  182.   };
  183.   uint32 returnvalue;
  184.   uint32 sum = bitindex + number_of_bits;
  185.  
  186.   if (sum <= 32)
  187.   {
  188.      // all bits contained in *wordpointer
  189.      returnvalue = (*wordpointer >> (32 - sum)) & bitmask[number_of_bits];
  190.      if ((bitindex += number_of_bits) == 32)
  191.      {
  192.         bitindex = 0;
  193.  
  194. /*        if ((char *)++wordpointer > (char *)buffer + framesize)
  195.         {
  196.     cerr << "Ibitstream::get_bits(): no more bits in buffer!\n";
  197.     exit (1);
  198.         } */
  199.         wordpointer++; // added by me!
  200.      }
  201.      return returnvalue;
  202.   }
  203.  
  204.   *((int16 *)&returnvalue + 1) = *(int16 *)wordpointer;
  205.  
  206.   wordpointer++; // Added by me!
  207.   *(int16 *)&returnvalue = *((int16 *)wordpointer + 1);
  208.  
  209.   returnvalue >>= 48 - sum;    // returnvalue >>= 16 - (number_of_bits - (32 - bitindex))
  210.   returnvalue &= bitmask[number_of_bits];
  211.   bitindex = sum - 32;
  212.   return returnvalue;
  213. }
  214.  
  215. // Layer III routines
  216.  
  217. BOOL Ibitstream::get_side_info(uint32 channels,
  218.                                          III_side_info_t *side_info)
  219. // Reads the side info from the stream, assuming the entire
  220. // frame has been read already.
  221. {
  222.     int ch, gr;
  223.  
  224.     side_info->main_data_begin = get_bits(9);
  225.     if (channels == 1)
  226.         side_info->private_bits = get_bits(5);
  227.     else side_info->private_bits = get_bits(3);
  228.  
  229.     for (ch=0; ch<channels; ch++)
  230. //        for (i=0; i<4; i++)
  231.     side_info->ch[ch].scfsi[0] = get_bits(1);
  232.     side_info->ch[ch].scfsi[1] = get_bits(1);
  233.     side_info->ch[ch].scfsi[2] = get_bits(1);
  234.     side_info->ch[ch].scfsi[3] = get_bits(1);
  235.  
  236.     for (gr=0; gr<2; gr++) {
  237.         for (ch=0; ch<channels; ch++) {
  238.             side_info->ch[ch].gr[gr].part2_3_length = get_bits(12);
  239.             side_info->ch[ch].gr[gr].big_values = get_bits(9);
  240.             side_info->ch[ch].gr[gr].global_gain = get_bits(8);
  241.             side_info->ch[ch].gr[gr].scalefac_compress = get_bits(4);
  242.             side_info->ch[ch].gr[gr].window_switching_flag = get_bits(1);
  243.             if (side_info->ch[ch].gr[gr].window_switching_flag) {
  244.                 side_info->ch[ch].gr[gr].block_type = get_bits( 2);
  245.                 side_info->ch[ch].gr[gr].mixed_block_flag = get_bits(1);
  246. //                for (i=0; i<2; i++)
  247.                 side_info->ch[ch].gr[gr].table_select[0] = get_bits(5);
  248.                 side_info->ch[ch].gr[gr].table_select[1] = get_bits(5);
  249.  
  250. //                for (i=0; i<3; i++)
  251.                 side_info->ch[ch].gr[gr].subblock_gain[0] = get_bits(3);
  252.                 side_info->ch[ch].gr[gr].subblock_gain[1] = get_bits(3);
  253.                 side_info->ch[ch].gr[gr].subblock_gain[2] = get_bits(3);
  254.  
  255.                 /* Set region_count parameters since they are implicit in this case. */
  256.  
  257.                 if (side_info->ch[ch].gr[gr].block_type == 0) {
  258. /*                    printf("Side info bad: block_type == 0 in split block.\n");
  259.                     exit(0); */
  260.                     return(FALSE);
  261.                 } else if (side_info->ch[ch].gr[gr].block_type == 2
  262.                             && side_info->ch[ch].gr[gr].mixed_block_flag == 0)
  263.                     side_info->ch[ch].gr[gr].region0_count = 8; /* MI 9; */
  264.                 else side_info->ch[ch].gr[gr].region0_count = 7; /* MI 8; */
  265.                 side_info->ch[ch].gr[gr].region1_count = 20 -
  266.                         side_info->ch[ch].gr[gr].region0_count;
  267.                 }
  268.             else {
  269. //                for (i=0; i<3; i++)
  270.                     side_info->ch[ch].gr[gr].table_select[0] = get_bits(5);
  271.                     side_info->ch[ch].gr[gr].table_select[1] = get_bits(5);
  272.                     side_info->ch[ch].gr[gr].table_select[2] = get_bits(5);
  273.  
  274.                 side_info->ch[ch].gr[gr].region0_count = get_bits(4);
  275.                 side_info->ch[ch].gr[gr].region1_count = get_bits(3);
  276.                 side_info->ch[ch].gr[gr].block_type = 0;
  277.                 }
  278.             side_info->ch[ch].gr[gr].preflag = get_bits(1);
  279.             side_info->ch[ch].gr[gr].scalefac_scale = get_bits(1);
  280.             side_info->ch[ch].gr[gr].count1table_select = get_bits(1);
  281.             }
  282.         }
  283.         return(TRUE);
  284. }
  285.  
  286. DWORD Ibitstream::file_size()
  287. {
  288.     return (GetFileSize(FH, NULL));
  289. }
  290.  
  291. DWORD Ibitstream::seek(int32 frame, int32 frame_size)
  292. {
  293.     current_frame = frame - 1;
  294.     return (SetFilePointer(FH, frame * (frame_size + 4), NULL, FILE_BEGIN));
  295. }
  296.  
  297. DWORD Ibitstream::seek_pad(int32 frame, int32 base_frame_size)
  298. {
  299.     // base_frame_size is the frame size _without_ padding.
  300.  
  301.     Header header;
  302.     Crc16 *crc;
  303.  
  304.     int32 total_frame_size = base_frame_size + 4;
  305.     int32 diff;
  306.  
  307.     if (last_frame_number < frame - 1) {
  308.         diff = (last_frame_number >= 0) ?  offset[last_frame_number] : 0;
  309.         SetFilePointer(FH, (last_frame_number + 1) * total_frame_size +
  310.                             diff, NULL, FILE_BEGIN);
  311.  
  312.         current_frame = last_frame_number;
  313.  
  314.         do {
  315.             if (!header.read_header(this, &crc)) // will increment last_frame_number
  316.                 return(0L);
  317.         } while (last_frame_number < frame -1);
  318.  
  319.  
  320.     } else {
  321.         diff = (frame > 0) ? offset[frame - 1] : 0;
  322.         SetFilePointer(FH, frame * total_frame_size + diff, NULL, FILE_BEGIN);
  323.         current_frame = frame - 1;
  324.     }
  325.  
  326.     return (1L);
  327. }
  328.  
  329.  
  330.