diff options
Diffstat (limited to 'embdrv/sbc/encoder/srce/sbc_enc_bit_alloc_ste.c')
-rw-r--r-- | embdrv/sbc/encoder/srce/sbc_enc_bit_alloc_ste.c | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/embdrv/sbc/encoder/srce/sbc_enc_bit_alloc_ste.c b/embdrv/sbc/encoder/srce/sbc_enc_bit_alloc_ste.c new file mode 100644 index 0000000..cbcb809 --- /dev/null +++ b/embdrv/sbc/encoder/srce/sbc_enc_bit_alloc_ste.c @@ -0,0 +1,201 @@ +/****************************************************************************** +** +** File Name: $RCSfile: sbc_enc_bit_alloc_ste.c,v $ +** +** Description: This file contains the code for bit allocation algorithm. +** It calculates the number of bits required for the encoded stream of data. +** +** Revision : $Id: sbc_enc_bit_alloc_ste.c,v 1.9 2006/03/31 17:17:07 mjougit Exp $ +** +** Copyright (c) 1999-2002, Widcomm Inc., All Rights Reserved. +** Widcomm Bluetooth Core. Proprietary and confidential. +** +******************************************************************************/ + +/*Includes*/ +#include "sbc_encoder.h" +#include "sbc_enc_func_declare.h" + +/*global arrays*/ +extern const SINT16 sbc_enc_as16Offset4[4][4]; +extern const SINT16 sbc_enc_as16Offset8[4][8]; + +/**************************************************************************** +* BitAlloc - Calculates the required number of bits for the given scale factor +* and the number of subbands. +* +* RETURNS : N/A +*/ + +void sbc_enc_bit_alloc_ste(SBC_ENC_PARAMS *pstrCodecParams) +{ + /* CAUTIOM -> mips optim for arm 32 require to use SINT32 instead of SINT16 */ + /* Do not change variable type or name */ + SINT32 s32MaxBitNeed; /*to store the max bits needed per sb*/ + SINT32 s32BitCount; /*the used number of bits*/ + SINT32 s32SliceCount; /*to store hwo many slices can be put in bitpool*/ + SINT32 s32BitSlice; /*number of bitslices in bitpool*/ + SINT32 s32Sb; /*counter for sub-band*/ + SINT32 s32Ch; /*counter for channel*/ + SINT16 *ps16BitNeed; /*temp memory to store required number of bits*/ + SINT32 s32Loudness; /*used in Loudness calculation*/ + SINT16 *ps16GenBufPtr,*pas16ScaleFactor; + SINT16 *ps16GenArrPtr; + SINT16 *ps16GenTabPtr; + SINT32 s32NumOfSubBands = pstrCodecParams->s16NumOfSubBands; + SINT32 s32BitPool = pstrCodecParams->s16BitPool; + + /* bitneed values are derived from scale factor */ + if (pstrCodecParams->s16AllocationMethod == SBC_SNR) + { + ps16BitNeed = pstrCodecParams->as16ScaleFactor; + s32MaxBitNeed = pstrCodecParams->s16MaxBitNeed; + } + else + { + ps16BitNeed = pstrCodecParams->s16ScartchMemForBitAlloc; + pas16ScaleFactor=pstrCodecParams->as16ScaleFactor; + s32MaxBitNeed = 0; + ps16GenBufPtr = ps16BitNeed; + for (s32Ch = 0; s32Ch < 2; s32Ch++) + { + if (s32NumOfSubBands == 4) + { + ps16GenTabPtr = (SINT16 *)sbc_enc_as16Offset4[pstrCodecParams->s16SamplingFreq]; + } + else + { + ps16GenTabPtr = (SINT16 *)sbc_enc_as16Offset8[pstrCodecParams->s16SamplingFreq]; + } + + for (s32Sb = 0; s32Sb < s32NumOfSubBands; s32Sb++) + { + if (*pas16ScaleFactor == 0) + *ps16GenBufPtr = -5; + else + { + s32Loudness = (SINT32)(*pas16ScaleFactor - *ps16GenTabPtr); + + if (s32Loudness > 0) + *ps16GenBufPtr = (SINT16)(s32Loudness >> 1); + else + *ps16GenBufPtr = (SINT16)s32Loudness; + } + + if (*ps16GenBufPtr > s32MaxBitNeed) + s32MaxBitNeed = *ps16GenBufPtr; + pas16ScaleFactor++; + ps16GenBufPtr++; + ps16GenTabPtr++; + } + } + } + + /* iterative process to find out hwo many bitslices fit into the bitpool */ + s32BitSlice = s32MaxBitNeed + 1; + s32BitCount = s32BitPool; + s32SliceCount = 0; + do + { + s32BitSlice --; + s32BitCount -= s32SliceCount; + s32SliceCount = 0; + ps16GenBufPtr = ps16BitNeed; + + for (s32Sb = 0; s32Sb < 2*s32NumOfSubBands; s32Sb++) + { + if ( (*ps16GenBufPtr >= s32BitSlice + 1) && (*ps16GenBufPtr < s32BitSlice + 16) ) + { + if (*(ps16GenBufPtr) == s32BitSlice+1) + s32SliceCount += 2; + else + s32SliceCount++; + } + ps16GenBufPtr++; + } + } while (s32BitCount-s32SliceCount>0); + + if (s32BitCount-s32SliceCount == 0) + { + s32BitCount -= s32SliceCount; + s32BitSlice --; + } + + /* Bits are distributed until the last bitslice is reached */ + ps16GenBufPtr = ps16BitNeed; + ps16GenArrPtr = pstrCodecParams->as16Bits; + for (s32Ch = 0; s32Ch < 2; s32Ch++) + { + for (s32Sb = 0; s32Sb < s32NumOfSubBands; s32Sb++) + { + if (*ps16GenBufPtr < s32BitSlice+2) + *ps16GenArrPtr = 0; + else + *ps16GenArrPtr = ((*(ps16GenBufPtr)-s32BitSlice) < 16) ? + (SINT16)(*(ps16GenBufPtr)-s32BitSlice):16; + ps16GenBufPtr++; + ps16GenArrPtr++; + } + } + + /* the remaining bits are allocated starting at subband 0 */ + s32Ch=0; + s32Sb=0; + ps16GenBufPtr = ps16BitNeed; + ps16GenArrPtr -= 2*s32NumOfSubBands; + + while ( (s32BitCount > 0) && (s32Sb < s32NumOfSubBands) ) + { + if ( (*(ps16GenArrPtr) >= 2) && (*(ps16GenArrPtr) < 16) ) + { + (*(ps16GenArrPtr))++; + s32BitCount--; + } + else if ((*ps16GenBufPtr == s32BitSlice+1) && (s32BitCount > 1)) + { + *(ps16GenArrPtr) = 2; + s32BitCount -= 2; + } + if(s32Ch == 1) + { + s32Ch = 0; + s32Sb++; + ps16GenBufPtr = ps16BitNeed+s32Sb; + ps16GenArrPtr = pstrCodecParams->as16Bits+s32Sb; + + } + else + { + s32Ch =1; + ps16GenBufPtr = ps16BitNeed+s32NumOfSubBands+s32Sb; + ps16GenArrPtr = pstrCodecParams->as16Bits+s32NumOfSubBands+s32Sb; + } + } + + s32Ch=0; + s32Sb=0; + ps16GenArrPtr = pstrCodecParams->as16Bits; + + while ((s32BitCount >0) && (s32Sb < s32NumOfSubBands)) + { + if(*(ps16GenArrPtr) < 16) + { + (*(ps16GenArrPtr))++; + s32BitCount--; + } + if (s32Ch == 1) + { + s32Ch = 0; + s32Sb++; + ps16GenArrPtr = pstrCodecParams->as16Bits+s32Sb; + } + else + { + s32Ch = 1; + ps16GenArrPtr = pstrCodecParams->as16Bits+s32NumOfSubBands+s32Sb; + } + } +} + +/*End of BitAlloc() function*/ + |