200 lines
7.2 KiB
C
200 lines
7.2 KiB
C
|
/******************************************************************************
|
||
|
*
|
||
|
* 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*/
|