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_enc_func_declare.h"
     26 #include "sbc_encoder.h"
     27 
     28 #if (SBC_ARM_ASM_OPT == TRUE)
     29 #define Mult32(s32In1, s32In2, s32OutLow)    \
     30   {                                          \
     31     __asm {                                                                                    \
     32         MUL s32OutLow,s32In1,s32In2; } \
     33   }
     34 #define Mult64(s32In1, s32In2, s32OutLow, s32OutHi)     \
     35   {                                                     \
     36     __asm {														    						\
     37         SMULL s32OutLow,s32OutHi,s32In1,s32In2 } \
     38   }
     39 #else
     40 #define Mult32(s32In1, s32In2, s32OutLow) \
     41   s32OutLow = (int32_t)(s32In1) * (int32_t)(s32In2);
     42 #define Mult64(s32In1, s32In2, s32OutLow, s32OutHi)                   \
     43   {                                                                   \
     44     (s32OutLow) = ((int32_t)(uint16_t)(s32In1) * (uint16_t)(s32In2)); \
     45     s32TempVal2 = (int32_t)(((s32In1) >> 16) * (uint16_t)(s32In2));   \
     46     s32Carry = ((((uint32_t)(s32OutLow) >> 16) & 0xFFFF) +            \
     47                 +(s32TempVal2 & 0xFFFF)) >>                           \
     48                16;                                                    \
     49     (s32OutLow) += (s32TempVal2 << 16);                               \
     50     (s32OutHi) = (s32TempVal2 >> 16) + s32Carry;                      \
     51   }
     52 #endif
     53 
     54 /* return number of bytes written to output */
     55 uint32_t EncPacking(SBC_ENC_PARAMS* pstrEncParams, uint8_t* output) {
     56   uint8_t* pu8PacketPtr; /* packet ptr*/
     57   uint8_t Temp;
     58   int32_t s32Blk;        /* counter for block*/
     59   int32_t s32Ch;         /* counter for channel*/
     60   int32_t s32Sb;         /* counter for sub-band*/
     61   int32_t s32PresentBit; /* represents bit to be stored*/
     62   /*int32_t s32LoopCountI;                       loop counter*/
     63   int32_t s32LoopCountJ; /* loop counter*/
     64   uint32_t u32QuantizedSbValue,
     65       u32QuantizedSbValue0; /* temp variable to store quantized sb val*/
     66   int32_t s32LoopCount;     /* loop counter*/
     67   uint8_t u8XoredVal;       /* to store XORed value in CRC calculation*/
     68   uint8_t u8CRC;            /* to store CRC value*/
     69   int16_t* ps16GenPtr;
     70   int32_t s32NumOfBlocks;
     71   int32_t s32NumOfSubBands = pstrEncParams->s16NumOfSubBands;
     72   int32_t s32NumOfChannels = pstrEncParams->s16NumOfChannels;
     73   uint32_t u32SfRaisedToPow2; /*scale factor raised to power 2*/
     74   int16_t* ps16ScfPtr;
     75   int32_t* ps32SbPtr;
     76   uint16_t u16Levels; /*to store levels*/
     77   int32_t s32Temp1;   /*used in 64-bit multiplication*/
     78   int32_t s32Low;     /*used in 64-bit multiplication*/
     79 #if (SBC_IS_64_MULT_IN_QUANTIZER == TRUE)
     80   int32_t s32Hi1, s32Low1, s32Carry, s32TempVal2, s32Hi, s32Temp2;
     81 #endif
     82 
     83   pu8PacketPtr = output;           /*Initialize the ptr*/
     84   *pu8PacketPtr++ = (uint8_t)0x9C; /*Sync word*/
     85   *pu8PacketPtr++ = (uint8_t)(pstrEncParams->FrameHeader);
     86 
     87   *pu8PacketPtr = (uint8_t)(pstrEncParams->s16BitPool & 0x00FF);
     88   pu8PacketPtr += 2; /*skip for CRC*/
     89 
     90   /*here it indicate if it is byte boundary or nibble boundary*/
     91   s32PresentBit = 8;
     92   Temp = 0;
     93 #if (SBC_JOINT_STE_INCLUDED == TRUE)
     94   if (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO) {
     95     /* pack join stero parameters */
     96     for (s32Sb = 0; s32Sb < s32NumOfSubBands; s32Sb++) {
     97       Temp <<= 1;
     98       Temp |= pstrEncParams->as16Join[s32Sb];
     99     }
    100 
    101     /* pack RFA */
    102     if (s32NumOfSubBands == SUB_BANDS_4) {
    103       s32PresentBit = 4;
    104     } else {
    105       *(pu8PacketPtr++) = Temp;
    106       Temp = 0;
    107     }
    108   }
    109 #endif
    110 
    111   /* Pack Scale factor */
    112   ps16GenPtr = pstrEncParams->as16ScaleFactor;
    113   s32Sb = s32NumOfChannels * s32NumOfSubBands;
    114   /*Temp=*pu8PacketPtr;*/
    115   for (s32Ch = s32Sb; s32Ch > 0; s32Ch--) {
    116     Temp <<= 4;
    117     Temp |= *ps16GenPtr++;
    118 
    119     if (s32PresentBit == 4) {
    120       s32PresentBit = 8;
    121       *(pu8PacketPtr++) = Temp;
    122       Temp = 0;
    123     } else {
    124       s32PresentBit = 4;
    125     }
    126   }
    127 
    128   /* Pack samples */
    129   ps32SbPtr = pstrEncParams->s32SbBuffer;
    130   /*Temp=*pu8PacketPtr;*/
    131   s32NumOfBlocks = pstrEncParams->s16NumOfBlocks;
    132   for (s32Blk = s32NumOfBlocks - 1; s32Blk >= 0; s32Blk--) {
    133     ps16GenPtr = pstrEncParams->as16Bits;
    134     ps16ScfPtr = pstrEncParams->as16ScaleFactor;
    135     for (s32Ch = s32Sb - 1; s32Ch >= 0; s32Ch--) {
    136       s32LoopCount = *ps16GenPtr++;
    137       if (s32LoopCount != 0) {
    138 #if (SBC_IS_64_MULT_IN_QUANTIZER == TRUE)
    139         /* finding level from reconstruction part of decoder */
    140         u32SfRaisedToPow2 = ((uint32_t)1 << ((*ps16ScfPtr) + 1));
    141         u16Levels = (uint16_t)(((uint32_t)1 << s32LoopCount) - 1);
    142 
    143         /* quantizer */
    144         s32Temp1 = (*ps32SbPtr >> 2) + (u32SfRaisedToPow2 << 12);
    145         s32Temp2 = u16Levels;
    146 
    147         Mult64(s32Temp1, s32Temp2, s32Low, s32Hi);
    148 
    149         s32Low1 = s32Low >> ((*ps16ScfPtr) + 2);
    150         s32Low1 &= ((uint32_t)1 << (32 - ((*ps16ScfPtr) + 2))) - 1;
    151         s32Hi1 = s32Hi << (32 - ((*ps16ScfPtr) + 2));
    152 
    153         u32QuantizedSbValue0 = (uint16_t)((s32Low1 | s32Hi1) >> 12);
    154 #else
    155         /* finding level from reconstruction part of decoder */
    156         u32SfRaisedToPow2 = ((uint32_t)1 << *ps16ScfPtr);
    157         u16Levels = (uint16_t)(((uint32_t)1 << s32LoopCount) - 1);
    158 
    159         /* quantizer */
    160         s32Temp1 = (*ps32SbPtr >> 15) + u32SfRaisedToPow2;
    161         Mult32(s32Temp1, u16Levels, s32Low);
    162         s32Low >>= (*ps16ScfPtr + 1);
    163         u32QuantizedSbValue0 = (uint16_t)s32Low;
    164 #endif
    165         /*store the number of bits required and the quantized s32Sb
    166         sample to ease the coding*/
    167         u32QuantizedSbValue = u32QuantizedSbValue0;
    168 
    169         if (s32PresentBit >= s32LoopCount) {
    170           Temp <<= s32LoopCount;
    171           Temp |= u32QuantizedSbValue;
    172           s32PresentBit -= s32LoopCount;
    173         } else {
    174           while (s32PresentBit < s32LoopCount) {
    175             s32LoopCount -= s32PresentBit;
    176             u32QuantizedSbValue >>= s32LoopCount;
    177 
    178             /*remove the unwanted msbs*/
    179             /*u32QuantizedSbValue <<= 16 - s32PresentBit;
    180             u32QuantizedSbValue >>= 16 - s32PresentBit;*/
    181 
    182             Temp <<= s32PresentBit;
    183 
    184             Temp |= u32QuantizedSbValue;
    185             /*restore the original*/
    186             u32QuantizedSbValue = u32QuantizedSbValue0;
    187 
    188             *(pu8PacketPtr++) = Temp;
    189             Temp = 0;
    190             s32PresentBit = 8;
    191           }
    192           Temp <<= s32LoopCount;
    193 
    194           /* remove the unwanted msbs */
    195           /*u32QuantizedSbValue <<= 16 - s32LoopCount;
    196           u32QuantizedSbValue >>= 16 - s32LoopCount;*/
    197 
    198           Temp |= u32QuantizedSbValue;
    199 
    200           s32PresentBit -= s32LoopCount;
    201         }
    202       }
    203       ps16ScfPtr++;
    204       ps32SbPtr++;
    205     }
    206   }
    207 
    208   Temp <<= s32PresentBit;
    209   *pu8PacketPtr = Temp;
    210   uint32_t u16PacketLength = pu8PacketPtr - output + 1;
    211   /*find CRC*/
    212   pu8PacketPtr = output + 1; /*Initialize the ptr*/
    213   u8CRC = 0x0F;
    214   s32LoopCount = s32Sb >> 1;
    215 
    216   /*
    217   The loops is run from the start of the packet till the scale factor
    218   parameters. In case of JS, 'join' parameter is included in the packet
    219   so that many more bytes are included in CRC calculation.
    220   */
    221   Temp = *pu8PacketPtr;
    222   for (s32Ch = 1; s32Ch < (s32LoopCount + 4); s32Ch++) {
    223     /* skip sync word and CRC bytes */
    224     if (s32Ch != 3) {
    225       for (s32LoopCountJ = 7; s32LoopCountJ >= 0; s32LoopCountJ--) {
    226         u8XoredVal = ((u8CRC >> 7) & 0x01) ^ ((Temp >> s32LoopCountJ) & 0x01);
    227         u8CRC <<= 1;
    228         u8CRC ^= (u8XoredVal * 0x1D);
    229         u8CRC &= 0xFF;
    230       }
    231     }
    232     Temp = *(++pu8PacketPtr);
    233   }
    234 
    235   if (pstrEncParams->s16ChannelMode == SBC_JOINT_STEREO) {
    236     for (s32LoopCountJ = 7; s32LoopCountJ >= (8 - s32NumOfSubBands);
    237          s32LoopCountJ--) {
    238       u8XoredVal = ((u8CRC >> 7) & 0x01) ^ ((Temp >> s32LoopCountJ) & 0x01);
    239       u8CRC <<= 1;
    240       u8CRC ^= (u8XoredVal * 0x1D);
    241       u8CRC &= 0xFF;
    242     }
    243   }
    244 
    245   /* CRC calculation ends here */
    246 
    247   /* store CRC in packet */
    248   output[3] = u8CRC;
    249   return u16PacketLength;
    250 }
    251