text: /**********
  This library is free software; you can redistribute it and/or modify it under
  the terms of the GNU Lesser General Public License as published by the
  Free Software Foundation; either version 2.1 of the License, or (at your
  option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
  
  This library is distributed in the hope that it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
  more details.
  
  You should have received a copy of the GNU Lesser General Public License
  along with this library; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
  **********/
  // "liveMedia"
  // Copyright (c) 1996-2015 Live Networks, Inc.  All rights reserved.
  // MP3 internal implementation details
  // C++ header
  
  #ifndef _MP3_INTERNALS_HH
  #define _MP3_INTERNALS_HH
  
  #ifndef _BOOLEAN_HH
  #include "Boolean.hh"
  #endif
  #ifndef _BIT_VECTOR_HH
  #include "BitVector.hh"
  #endif
  
  typedef struct MP3SideInfo {
    unsigned main_data_begin;
    unsigned private_bits;
    typedef struct gr_info_s {
      int scfsi;
      unsigned part2_3_length;
      unsigned big_values;
      unsigned global_gain;
      unsigned scalefac_compress;
      unsigned window_switching_flag;
      unsigned block_type;
      unsigned mixed_block_flag;
      unsigned table_select[3];
      unsigned region0_count;
      unsigned region1_count;
      unsigned subblock_gain[3];
      unsigned maxband[3];
      unsigned maxbandl;
      unsigned maxb;
      unsigned region1start;
      unsigned region2start;
      unsigned preflag;
      unsigned scalefac_scale;
      unsigned count1table_select;
      double *full_gain[3];
      double *pow2gain;
    } gr_info_s_t;
    struct {
      gr_info_s_t gr[2];
    } ch[2];
  } MP3SideInfo_t;
  
  #define SBLIMIT 32
  #define MAX_MP3_FRAME_SIZE 2500 /* also big enough for an 'ADU'ized frame */
  
  class MP3FrameParams {
  public:
    MP3FrameParams();
    ~MP3FrameParams();
  
    // 4-byte MPEG header:
    unsigned hdr;
  
    // a buffer that can be used to hold the rest of the frame:
    unsigned char frameBytes[MAX_MP3_FRAME_SIZE];
  
    // public parameters derived from the header
    void setParamsFromHeader(); // this sets them
    Boolean isMPEG2;
    unsigned layer; // currently only 3 is supported
    unsigned bitrate; // in kbps
    unsigned samplingFreq;
    Boolean isStereo;
    Boolean isFreeFormat;
    unsigned frameSize; // doesn't include the initial 4-byte header
    unsigned sideInfoSize;
    Boolean hasCRC;
  
    void setBytePointer(unsigned char const* restOfFrame,
  		      unsigned totNumBytes) {// called during setup
      bv.setup((unsigned char*)restOfFrame, 0, 8*totNumBytes);
    }
  
    // other, public parameters used when parsing input (perhaps get rid of)
    unsigned oldHdr, firstHdr;
  
    // Extract (unpack) the side info from the frame into a struct:
    void getSideInfo(MP3SideInfo& si);
  
    // The bit pointer used for reading data from frame data
    unsigned getBits(unsigned numBits) { return bv.getBits(numBits); }
    unsigned get1Bit() { return bv.get1Bit(); }
  
  private:
    BitVector bv;
  
    // other, private parameters derived from the header
    unsigned bitrateIndex;
    unsigned samplingFreqIndex;
    Boolean isMPEG2_5;
    Boolean padding;
    Boolean extension;
    unsigned mode;
    unsigned mode_ext;
    Boolean copyright;
    Boolean original;
    unsigned emphasis;
    unsigned stereo;
  
  private:
    unsigned computeSideInfoSize();
  };
  
  unsigned ComputeFrameSize(unsigned bitrate, unsigned samplingFreq,
  			  Boolean usePadding, Boolean isMPEG2,
  			  unsigned char layer);
  
  Boolean GetADUInfoFromMP3Frame(unsigned char const* framePtr,
  			       unsigned totFrameSize,
  			       unsigned& hdr, unsigned& frameSize,
  			       MP3SideInfo& sideInfo, unsigned& sideInfoSize,
  			       unsigned& backpointer, unsigned& aduSize);
  
  Boolean ZeroOutMP3SideInfo(unsigned char* framePtr, unsigned totFrameSize,
  			   unsigned newBackpointer);
  
  unsigned TranscodeMP3ADU(unsigned char const* fromPtr, unsigned fromSize,
  		      unsigned toBitrate,
  		      unsigned char* toPtr, unsigned toMaxSize,
  		      unsigned& availableBytesForBackpointer);
    // returns the size of the resulting ADU (0 on failure)
  
  #endif
  