Home | History | Annotate | Download | only in srce
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 1999-2012 Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 /******************************************************************************
     20  *
     21  *  This file contains code for packing the Encoded data into bit streams.
     22  *
     23  ******************************************************************************/
     24 
     25 #include "sbc_encoder.h"
     26 #include "sbc_enc_func_declare.h"
     27 
     28 #if (SBC_ARM_ASM_OPT==TRUE)
     29 #define Mult32(s32In1,s32In2,s32OutLow)                                                 \
     30 {                                                                                       \
     31    __asm                                                                                \
     32    {                                                                                    \
     33         MUL s32OutLow,s32In1,s32In2;                                                    \
     34     }                                                                                   \
     35 }
     36 #define Mult64(s32In1, s32In2, s32OutLow, s32OutHi)                                     \
     37 {                                                                                       \
     38     __asm													        					\
     39     {														    						\
     40         SMULL s32OutLow,s32OutHi,s32In1,s32In2          	    						\
     41     }														    						\
     42 }
     43 #else
     44 #define Mult32(s32In1,s32In2,s32OutLow) s32OutLow=(SINT32)s32In1*(SINT32)s32In2;
     45 #define Mult64(s32In1, s32In2, s32OutLow, s32OutHi)                                     \
     46 {                                                                                       \
     47 	s32OutLow   = ((SINT32)(UINT16)s32In1  * (UINT16)s32In2);                           \
     48 	s32TempVal2 = (SINT32)((s32In1 >> 16) * (UINT16)s32In2);                            \
     49 	s32Carry    = ( (((UINT32)(s32OutLow)>>16)&0xFFFF) +                                \
     50 										+ (s32TempVal2 & 0xFFFF) ) >> 16;               \
     51 	s32OutLow   += (s32TempVal2 << 16);                                                 \
     52 	s32OutHi     = (s32TempVal2 >> 16) + s32Carry;                                      \
     53 }
     54 #endif
     55 
     56 void EncPacking(SBC_ENC_PARAMS *pstrEncParams)
     57 {
     58     UINT8       *pu8PacketPtr;                      /* packet ptr*/
     59     UINT8 Temp;
     60     SINT32      s32Blk;                             /* counter for block*/
     61     SINT32      s32Ch;                              /* counter for channel*/
     62     SINT32      s32Sb;                              /* counter for sub-band*/
     63     SINT32 s32PresentBit;                      /* represents bit to be stored*/
     64     /*SINT32 s32LoopCountI;                       loop counter*/
     65     SINT32 s32LoopCountJ;                      /* loop counter*/
     66     UINT32 u32QuantizedSbValue,u32QuantizedSbValue0; /* temp variable to store quantized sb val*/
     67     SINT32 s32LoopCount;                       /* loop counter*/
     68     UINT8 u8XoredVal;                         /* to store XORed value in CRC calculation*/
     69     UINT8 u8CRC;                              /* to store CRC value*/
     70     SINT16 *ps16GenPtr;
     71     SINT32 s32NumOfBlocks;
     72     SINT32 s32NumOfSubBands = pstrEncParams->s16NumOfSubBands;
     73     SINT32 s32NumOfChannels = pstrEncParams->s16NumOfChannels;
     74 	UINT32 u32SfRaisedToPow2;	/*scale factor raised to power 2*/
     75     SINT16 *ps16ScfPtr;
     76     SINT32 *ps32SbPtr;
     77 	UINT16 u16Levels;	/*to store levels*/
     78 	SINT32 s32Temp1;	/*used in 64-bit multiplication*/
     79 	SINT32 s32Low;	/*used in 64-bit multiplication*/
     80 #if (SBC_IS_64_MULT_IN_QUANTIZER==TRUE)
     81 	SINT32 s32Hi1,s32Low1,s32Carry,s32TempVal2,s32Hi, s32Temp2;
     82 #endif
     83 
     84     pu8PacketPtr    = pstrEncParams->pu8NextPacket;    /*Initialize the ptr*/
     85     *pu8PacketPtr++ = (UINT8)0x9C;  /*Sync word*/
     86     *pu8PacketPtr++=(UINT8)(pstrEncParams->FrameHeader);
     87 
     88     *pu8PacketPtr = (UINT8)(pstrEncParams->s16BitPool & 0x00FF);
     89     pu8PacketPtr += 2;  /*skip for CRC*/
     90 
     91     /*here it indicate if it is byte boundary or nibble boundary*/
     92     s32PresentBit = 8;
     93     Temp=0;
     94 #if (SBC_JOINT_STE_INCLUDED == TRUE)
     95     if (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO)
     96     {
     97         /* pack join stero parameters */
     98         for (s32Sb = 0; s32Sb < s32NumOfSubBands; s32Sb++)
     99         {
    100             Temp <<= 1;
    101             Temp |= pstrEncParams->as16Join[s32Sb];
    102         }
    103 
    104         /* pack RFA */
    105         if (s32NumOfSubBands == SUB_BANDS_4)
    106         {
    107             s32PresentBit = 4;
    108         }
    109         else
    110         {
    111             *(pu8PacketPtr++)=Temp;
    112             Temp = 0;
    113         }
    114     }
    115 #endif
    116 
    117     /* Pack Scale factor */
    118     ps16GenPtr = pstrEncParams->as16ScaleFactor;
    119     s32Sb=s32NumOfChannels*s32NumOfSubBands;
    120     /*Temp=*pu8PacketPtr;*/
    121     for (s32Ch = s32Sb; s32Ch >0; s32Ch--)
    122     {
    123         Temp<<= 4;
    124         Temp |= *ps16GenPtr++;
    125 
    126         if(s32PresentBit == 4)
    127         {
    128             s32PresentBit = 8;
    129             *(pu8PacketPtr++)=Temp;
    130             Temp = 0;
    131         }
    132         else
    133         {
    134             s32PresentBit = 4;
    135         }
    136     }
    137 
    138     /* Pack samples */
    139     ps32SbPtr   = pstrEncParams->s32SbBuffer;
    140     /*Temp=*pu8PacketPtr;*/
    141     s32NumOfBlocks= pstrEncParams->s16NumOfBlocks;
    142     for (s32Blk = s32NumOfBlocks-1; s32Blk >=0; s32Blk--)
    143     {
    144         ps16GenPtr  = pstrEncParams->as16Bits;
    145         ps16ScfPtr  = pstrEncParams->as16ScaleFactor;
    146         for (s32Ch = s32Sb-1; s32Ch >= 0; s32Ch--)
    147         {
    148             s32LoopCount = *ps16GenPtr++;
    149             if (s32LoopCount != 0)
    150             {
    151 #if (SBC_IS_64_MULT_IN_QUANTIZER==TRUE)
    152                 /* finding level from reconstruction part of decoder */
    153                 u32SfRaisedToPow2 = ((UINT32)1 << ((*ps16ScfPtr)+1));
    154                 u16Levels = (UINT16)(((UINT32)1 << s32LoopCount) - 1);
    155 
    156                 /* quantizer */
    157                 s32Temp1 = (*ps32SbPtr >> 2) + (u32SfRaisedToPow2 << 12);
    158                 s32Temp2 = u16Levels;
    159 
    160                 Mult64 (s32Temp1, s32Temp2, s32Low, s32Hi);
    161 
    162                 s32Low1   = s32Low >> ((*ps16ScfPtr)+2);
    163                 s32Low1  &= ((UINT32)1 << (32 - ((*ps16ScfPtr)+2))) - 1;
    164                 s32Hi1    = s32Hi << (32 - ((*ps16ScfPtr) +2));
    165 
    166                 u32QuantizedSbValue0 = (UINT16)((s32Low1 | s32Hi1) >> 12);
    167 #else
    168                 /* finding level from reconstruction part of decoder */
    169                 u32SfRaisedToPow2 = ((UINT32)1 << *ps16ScfPtr);
    170                 u16Levels = (UINT16)(((UINT32)1 << s32LoopCount)-1);
    171 
    172                 /* quantizer */
    173                 s32Temp1 = (*ps32SbPtr >> 15) + u32SfRaisedToPow2;
    174                 Mult32(s32Temp1,u16Levels,s32Low);
    175                 s32Low>>= (*ps16ScfPtr+1);
    176                 u32QuantizedSbValue0 = (UINT16)s32Low;
    177 #endif
    178                 /*store the number of bits required and the quantized s32Sb
    179                 sample to ease the coding*/
    180                 u32QuantizedSbValue = u32QuantizedSbValue0;
    181 
    182                 if(s32PresentBit >= s32LoopCount)
    183                 {
    184                     Temp <<= s32LoopCount;
    185                     Temp |= u32QuantizedSbValue;
    186                     s32PresentBit -= s32LoopCount;
    187                 }
    188                 else
    189                 {
    190                     while (s32PresentBit < s32LoopCount)
    191                     {
    192                         s32LoopCount -= s32PresentBit;
    193                         u32QuantizedSbValue >>= s32LoopCount;
    194 
    195                         /*remove the unwanted msbs*/
    196                         /*u32QuantizedSbValue <<= 16 - s32PresentBit;
    197                         u32QuantizedSbValue >>= 16 - s32PresentBit;*/
    198 
    199                         Temp <<= s32PresentBit;
    200 
    201                         Temp |= u32QuantizedSbValue ;
    202                         /*restore the original*/
    203                         u32QuantizedSbValue=u32QuantizedSbValue0;
    204 
    205                         *(pu8PacketPtr++)=Temp;
    206                         Temp = 0;
    207                         s32PresentBit = 8;
    208                     }
    209                     Temp <<= s32LoopCount;
    210 
    211                     /* remove the unwanted msbs */
    212                     /*u32QuantizedSbValue <<= 16 - s32LoopCount;
    213                     u32QuantizedSbValue >>= 16 - s32LoopCount;*/
    214 
    215                     Temp |= u32QuantizedSbValue;
    216 
    217                     s32PresentBit -= s32LoopCount;
    218                 }
    219             }
    220             ps16ScfPtr++;
    221             ps32SbPtr++;
    222         }
    223     }
    224 
    225     Temp <<= s32PresentBit;
    226     *pu8PacketPtr=Temp;
    227     pstrEncParams->u16PacketLength=pu8PacketPtr-pstrEncParams->pu8NextPacket+1;
    228     /*find CRC*/
    229     pu8PacketPtr = pstrEncParams->pu8NextPacket+1;    /*Initialize the ptr*/
    230     u8CRC = 0x0F;
    231     s32LoopCount = s32Sb >> 1;
    232 
    233     /*
    234     The loops is run from the start of the packet till the scale factor
    235     parameters. In case of JS, 'join' parameter is included in the packet
    236     so that many more bytes are included in CRC calculation.
    237     */
    238     Temp=*pu8PacketPtr;
    239     for (s32Ch=1; s32Ch < (s32LoopCount+4); s32Ch++)
    240     {
    241         /* skip sync word and CRC bytes */
    242         if (s32Ch != 3)
    243         {
    244             for (s32LoopCountJ=7; s32LoopCountJ>=0; s32LoopCountJ--)
    245             {
    246                 u8XoredVal = ((u8CRC >> 7) & 0x01) ^((Temp >> s32LoopCountJ) & 0x01);
    247                 u8CRC <<= 1;
    248                 u8CRC ^= (u8XoredVal * 0x1D);
    249                 u8CRC &= 0xFF;
    250             }
    251         }
    252         Temp=*(++pu8PacketPtr);
    253     }
    254 
    255     if (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO)
    256     {
    257         for (s32LoopCountJ = 7; s32LoopCountJ >= (8 - s32NumOfSubBands); s32LoopCountJ--)
    258         {
    259             u8XoredVal = ((u8CRC >> 7) & 0x01) ^((Temp >> s32LoopCountJ) & 0x01);
    260             u8CRC <<= 1;
    261             u8CRC ^= (u8XoredVal * 0x1D);
    262             u8CRC &= 0xFF;
    263         }
    264     }
    265 
    266     /* CRC calculation ends here */
    267 
    268     /* store CRC in packet */
    269     pu8PacketPtr = pstrEncParams->pu8NextPacket;    /*Initialize the ptr*/
    270     pu8PacketPtr += 3;
    271     *pu8PacketPtr = u8CRC;
    272     pstrEncParams->pu8NextPacket+=pstrEncParams->u16PacketLength;  /* move the pointer to the end in case there is more than one frame to encode */
    273 }
    274 
    275