| /****************************************************************************** |
| * |
| * Copyright (C) 1999-2012 Broadcom Corporation |
| * |
| * 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. |
| * |
| ******************************************************************************/ |
| |
| /****************************************************************************** |
| * |
| * This file contains the code for bit allocation algorithm. It calculates |
| * the number of bits required for the encoded stream of data. |
| * |
| ******************************************************************************/ |
| |
| /*Includes*/ |
| #include "sbc_encoder.h" |
| #include "sbc_enc_func_declare.h" |
| |
| /*global arrays*/ |
| const SINT16 sbc_enc_as16Offset4[4][4] = { {-1, 0, 0, 0}, {-2, 0, 0, 1}, |
| {-2, 0, 0, 1}, {-2, 0, 0, 1} }; |
| const SINT16 sbc_enc_as16Offset8[4][8] = { {-2, 0, 0, 0, 0, 0, 0, 1}, |
| {-3, 0, 0, 0, 0, 0, 1, 2}, |
| {-4, 0, 0, 0, 0, 0, 1, 2}, |
| {-4, 0, 0, 0, 0, 0, 1, 2} }; |
| |
| /**************************************************************************** |
| * 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_mono(SBC_ENC_PARAMS *pstrCodecParams) |
| { |
| 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; |
| SINT16 *ps16GenArrPtr; |
| SINT16 *ps16GenTabPtr; |
| SINT32 s32NumOfSubBands = pstrCodecParams->s16NumOfSubBands; |
| |
| ps16BitNeed = pstrCodecParams->s16ScartchMemForBitAlloc; |
| |
| for (s32Ch = 0; s32Ch < pstrCodecParams->s16NumOfChannels; s32Ch++) |
| { |
| ps16GenBufPtr = ps16BitNeed + s32Ch*s32NumOfSubBands; |
| ps16GenArrPtr = pstrCodecParams->as16Bits+s32Ch*SBC_MAX_NUM_OF_SUBBANDS; |
| |
| /* bitneed values are derived from scale factor */ |
| if (pstrCodecParams->s16AllocationMethod == SBC_SNR) |
| { |
| ps16BitNeed = pstrCodecParams->as16ScaleFactor; |
| ps16GenBufPtr = ps16BitNeed + s32Ch * s32NumOfSubBands; |
| } |
| else |
| { |
| ps16GenBufPtr = ps16BitNeed + s32Ch*s32NumOfSubBands; |
| 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(pstrCodecParams->as16ScaleFactor[s32Ch*s32NumOfSubBands+s32Sb] == 0) |
| *(ps16GenBufPtr) = -5; |
| else |
| { |
| s32Loudness = |
| (SINT32)(pstrCodecParams->as16ScaleFactor[s32Ch*s32NumOfSubBands+s32Sb] |
| - *ps16GenTabPtr); |
| if(s32Loudness > 0) |
| *(ps16GenBufPtr) = (SINT16)(s32Loudness >>1); |
| else |
| *(ps16GenBufPtr) = (SINT16)s32Loudness; |
| } |
| ps16GenBufPtr++; |
| ps16GenTabPtr++; |
| } |
| |
| } |
| |
| /* max bitneed index is searched*/ |
| s32MaxBitNeed = 0; |
| ps16GenBufPtr = ps16BitNeed + s32Ch*s32NumOfSubBands; |
| for(s32Sb=0; s32Sb<s32NumOfSubBands; s32Sb++) |
| { |
| if( *(ps16GenBufPtr) > s32MaxBitNeed) |
| s32MaxBitNeed = *(ps16GenBufPtr); |
| |
| ps16GenBufPtr++; |
| } |
| ps16GenBufPtr = ps16BitNeed + s32Ch*s32NumOfSubBands; |
| /*iterative process to find hwo many bitslices fit into the bitpool*/ |
| s32BitSlice = s32MaxBitNeed + 1; |
| s32BitCount = pstrCodecParams->s16BitPool; |
| s32SliceCount = 0; |
| do |
| { |
| s32BitSlice --; |
| s32BitCount -= s32SliceCount; |
| s32SliceCount = 0; |
| |
| for(s32Sb=0; s32Sb<s32NumOfSubBands; s32Sb++) |
| { |
| if( (((*ps16GenBufPtr-s32BitSlice)< 16) && (*ps16GenBufPtr-s32BitSlice) >= 1)) |
| { |
| if((*ps16GenBufPtr-s32BitSlice) == 1) |
| s32SliceCount+=2; |
| else |
| s32SliceCount++; |
| } |
| ps16GenBufPtr++; |
| |
| }/*end of for*/ |
| ps16GenBufPtr = ps16BitNeed + s32Ch*s32NumOfSubBands; |
| }while(s32BitCount-s32SliceCount>0); |
| |
| if(s32BitCount == 0) |
| { |
| s32BitCount -= s32SliceCount; |
| s32BitSlice --; |
| } |
| |
| /*Bits are distributed until the last bitslice is reached*/ |
| ps16GenArrPtr = pstrCodecParams->as16Bits+s32Ch*s32NumOfSubBands; |
| ps16GenBufPtr = ps16BitNeed + s32Ch*s32NumOfSubBands; |
| for(s32Sb=0; s32Sb<s32NumOfSubBands; s32Sb++) |
| { |
| if(*(ps16GenBufPtr) < s32BitSlice+2) |
| *(ps16GenArrPtr) = 0; |
| else |
| *(ps16GenArrPtr) = ((*(ps16GenBufPtr)-s32BitSlice)<16) ? |
| (SINT16)(*(ps16GenBufPtr)-s32BitSlice) : 16; |
| |
| ps16GenBufPtr++; |
| ps16GenArrPtr++; |
| } |
| ps16GenArrPtr = pstrCodecParams->as16Bits+s32Ch*s32NumOfSubBands; |
| ps16GenBufPtr = ps16BitNeed + s32Ch*s32NumOfSubBands; |
| /*the remaining bits are allocated starting at subband 0*/ |
| s32Sb=0; |
| while( (s32BitCount > 0) && (s32Sb < s32NumOfSubBands) ) |
| { |
| if( (*(ps16GenArrPtr) >= 2) && (*(ps16GenArrPtr) < 16) ) |
| { |
| (*(ps16GenArrPtr))++; |
| s32BitCount--; |
| } |
| else if( (*(ps16GenBufPtr) == s32BitSlice+1) && |
| (s32BitCount > 1) ) |
| { |
| *(ps16GenArrPtr) = 2; |
| s32BitCount -= 2; |
| } |
| s32Sb++; |
| ps16GenArrPtr++; |
| ps16GenBufPtr++; |
| } |
| ps16GenArrPtr = pstrCodecParams->as16Bits+s32Ch*s32NumOfSubBands; |
| |
| |
| s32Sb=0; |
| while( (s32BitCount > 0) && (s32Sb < s32NumOfSubBands) ) |
| { |
| if( *(ps16GenArrPtr) < 16) |
| { |
| (*(ps16GenArrPtr))++; |
| s32BitCount--; |
| } |
| s32Sb++; |
| ps16GenArrPtr++; |
| } |
| } |
| } |
| /*End of BitAlloc() function*/ |