/* ------------------------------------------------------------------ * Copyright (C) 1998-2009 PacketVideo * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. * See the License for the specific language governing permissions * and limitations under the License. * ------------------------------------------------------------------- */ /* ------------------------------------------------------------------------------ PacketVideo Corp. MP3 Decoder Library Filename: pvmp3_getbits.cpp Date: 09/21/2007 ------------------------------------------------------------------------------ REVISION HISTORY Description: ------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: tmp3Bits *inputStream, structure holding the input stream parameters int32 neededBits number of bits to read from the bit stream Outputs: word parsed from teh bitstream, with size neededBits-bits, ------------------------------------------------------------------------------ FUNCTION DESCRIPTION ------------------------------------------------------------------------------ REQUIREMENTS ------------------------------------------------------------------------------ REFERENCES [1] ISO MPEG Audio Subgroup Software Simulation Group (1996) ISO 13818-3 MPEG-2 Audio Decoder - Lower Sampling Frequency Extension ------------------------------------------------------------------------------ PSEUDO-CODE ------------------------------------------------------------------------------ */ /*---------------------------------------------------------------------------- ; INCLUDES ----------------------------------------------------------------------------*/ #include "pvmp3_getbits.h" /*---------------------------------------------------------------------------- ; MACROS ; Define module specific macros here ----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- ; DEFINES ; Include all pre-processor statements here. Include conditional ; compile variables also. ----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- ; LOCAL FUNCTION DEFINITIONS ; Function Prototype declaration ----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- ; LOCAL STORE/BUFFER/POINTER DEFINITIONS ; Variable declaration - defined here and used outside this module ----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- ; EXTERNAL FUNCTION REFERENCES ; Declare functions defined elsewhere and referenced in this module ----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES ; Declare variables used in this module but defined elsewhere ----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- ; FUNCTION CODE ----------------------------------------------------------------------------*/ uint32 getNbits(tmp3Bits *ptBitStream, int32 neededBits) /* number of bits to read from the bitstream (up to 25) */ { uint32 offset; uint32 bitIndex; uint32 bytesToFetch; uint8 Elem = 0; /* Needs to be same type as pInput->pBuffer */ uint8 Elem1 = 0; uint8 Elem2 = 0; uint8 Elem3 = 0; uint32 returnValue = 0; if (!neededBits) { return (returnValue); } offset = (ptBitStream->usedBits) >> INBUF_ARRAY_INDEX_SHIFT; /* Remove extra high bits by shifting up */ bitIndex = module(ptBitStream->usedBits, INBUF_BIT_WIDTH); bytesToFetch = (bitIndex + neededBits + 7 ) >> 3 ; switch (bytesToFetch) { case 4: Elem3 = *(ptBitStream->pBuffer + module(offset + 3, BUFSIZE)); [[fallthrough]]; case 3: Elem2 = *(ptBitStream->pBuffer + module(offset + 2, BUFSIZE)); [[fallthrough]]; case 2: Elem1 = *(ptBitStream->pBuffer + module(offset + 1, BUFSIZE)); [[fallthrough]]; case 1: Elem = *(ptBitStream->pBuffer + module(offset, BUFSIZE)); } returnValue = (((uint32)(Elem)) << 24) | (((uint32)(Elem1)) << 16) | (((uint32)(Elem2)) << 8) | ((uint32)(Elem3)); /* This line is faster than to mask off the high bits. */ returnValue <<= bitIndex; /* Move the field down. */ returnValue >>= (32 - neededBits); ptBitStream->usedBits += neededBits; return (returnValue); } /*---------------------------------------------------------------------------- ; FUNCTION CODE ----------------------------------------------------------------------------*/ uint16 getUpTo9bits(tmp3Bits *ptBitStream, int32 neededBits) /* number of bits to read from the bit stream 2 to 9 */ { uint32 offset; uint32 bitIndex; uint32 bytesToFetch; uint8 Elem = 0; /* Needs to be same type as pInput->pBuffer */ uint8 Elem1 = 0; uint16 returnValue; offset = (ptBitStream->usedBits) >> INBUF_ARRAY_INDEX_SHIFT; /* Remove extra high bits by shifting up */ bitIndex = module(ptBitStream->usedBits, INBUF_BIT_WIDTH); bytesToFetch = (bitIndex + neededBits + 7 ) >> 3 ; if (bytesToFetch > 1) { Elem = *(ptBitStream->pBuffer + module(offset, BUFSIZE)); Elem1 = *(ptBitStream->pBuffer + module(offset + 1, BUFSIZE)); } else if (bytesToFetch > 0) { Elem = *(ptBitStream->pBuffer + module(offset, BUFSIZE)); } returnValue = (((uint16)(Elem)) << 8) | ((uint16)(Elem1)); ptBitStream->usedBits += neededBits; /* This line is faster than to mask off the high bits. */ returnValue = (returnValue << (bitIndex)); /* Move the field down. */ return (uint16)(returnValue >> (16 - neededBits)); } /*---------------------------------------------------------------------------- ; FUNCTION CODE ----------------------------------------------------------------------------*/ uint32 getUpTo17bits(tmp3Bits *ptBitStream, int32 neededBits) /* number of bits to read from the bit stream 2 to 8 */ { uint32 offset; uint32 bitIndex; uint32 bytesToFetch; uint8 Elem = 0; /* Needs to be same type as pInput->pBuffer */ uint8 Elem1 = 0; uint8 Elem2 = 0; uint32 returnValue; offset = (ptBitStream->usedBits) >> INBUF_ARRAY_INDEX_SHIFT; /* Remove extra high bits by shifting up */ bitIndex = module(ptBitStream->usedBits, INBUF_BIT_WIDTH); bytesToFetch = (bitIndex + neededBits + 7 ) >> 3 ; if (bytesToFetch > 2) { Elem = *(ptBitStream->pBuffer + module(offset, BUFSIZE)); Elem1 = *(ptBitStream->pBuffer + module(offset + 1, BUFSIZE)); Elem2 = *(ptBitStream->pBuffer + module(offset + 2, BUFSIZE)); } else if (bytesToFetch > 1) { Elem = *(ptBitStream->pBuffer + module(offset, BUFSIZE)); Elem1 = *(ptBitStream->pBuffer + module(offset + 1, BUFSIZE)); } else if (bytesToFetch > 0) { Elem = *(ptBitStream->pBuffer + module(offset, BUFSIZE)); } returnValue = (((uint32)(Elem)) << 16) | (((uint32)(Elem1)) << 8) | ((uint32)(Elem2)); ptBitStream->usedBits += neededBits; /* This line is faster than to mask off the high bits. */ returnValue = 0xFFFFFF & (returnValue << (bitIndex)); /* Move the field down. */ return (uint32)(returnValue >> (24 - neededBits)); } /*---------------------------------------------------------------------------- ; FUNCTION CODE ----------------------------------------------------------------------------*/ uint8 get1bit(tmp3Bits *ptBitStream) /* number of bits to read from the bit stream */ { uint32 offset; uint32 bitIndex; uint8 returnValue; offset = (ptBitStream->usedBits) >> INBUF_ARRAY_INDEX_SHIFT; returnValue = *(ptBitStream->pBuffer + module(offset , BUFSIZE)); /* Remove extra high bits by shifting up */ bitIndex = module(ptBitStream->usedBits, INBUF_BIT_WIDTH); ptBitStream->usedBits++; /* This line is faster than to mask off the high bits. */ returnValue = (returnValue << (bitIndex)); return (uint8)(returnValue >> 7); }