2016-11-04 07:08:30 +00:00
|
|
|
/******************************************************************************
|
|
|
|
*
|
|
|
|
* 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*/
|
2018-04-08 04:10:50 +00:00
|
|
|
#include "common/bt_target.h"
|
2016-11-04 07:08:30 +00:00
|
|
|
#include "sbc_encoder.h"
|
|
|
|
#include "sbc_enc_func_declare.h"
|
|
|
|
|
2017-03-17 07:57:30 +00:00
|
|
|
#if (defined(SBC_ENC_INCLUDED) && SBC_ENC_INCLUDED == TRUE)
|
|
|
|
|
2016-11-04 07:08:30 +00:00
|
|
|
/*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)
|
|
|
|
{
|
2016-11-26 05:09:55 +00:00
|
|
|
/* CAUTIOM -> mips optim for arm 32 require to use SINT32 instead of SINT16 */
|
|
|
|
/* Do not change variable type or name */
|
2016-11-04 07:08:30 +00:00
|
|
|
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*/
|
2016-11-26 05:09:55 +00:00
|
|
|
SINT16 *ps16GenBufPtr, *pas16ScaleFactor;
|
2016-11-04 07:08:30 +00:00
|
|
|
SINT16 *ps16GenArrPtr;
|
|
|
|
SINT16 *ps16GenTabPtr;
|
|
|
|
SINT32 s32NumOfSubBands = pstrCodecParams->s16NumOfSubBands;
|
|
|
|
SINT32 s32BitPool = pstrCodecParams->s16BitPool;
|
|
|
|
|
|
|
|
/* bitneed values are derived from scale factor */
|
2016-11-26 05:09:55 +00:00
|
|
|
if (pstrCodecParams->s16AllocationMethod == SBC_SNR) {
|
2016-11-04 07:08:30 +00:00
|
|
|
ps16BitNeed = pstrCodecParams->as16ScaleFactor;
|
|
|
|
s32MaxBitNeed = pstrCodecParams->s16MaxBitNeed;
|
2016-11-26 05:09:55 +00:00
|
|
|
} else {
|
2016-11-04 07:08:30 +00:00
|
|
|
ps16BitNeed = pstrCodecParams->s16ScartchMemForBitAlloc;
|
2016-11-26 05:09:55 +00:00
|
|
|
pas16ScaleFactor = pstrCodecParams->as16ScaleFactor;
|
2016-11-04 07:08:30 +00:00
|
|
|
s32MaxBitNeed = 0;
|
|
|
|
ps16GenBufPtr = ps16BitNeed;
|
2016-11-26 05:09:55 +00:00
|
|
|
for (s32Ch = 0; s32Ch < 2; s32Ch++) {
|
|
|
|
if (s32NumOfSubBands == 4) {
|
2016-11-04 07:08:30 +00:00
|
|
|
ps16GenTabPtr = (SINT16 *)sbc_enc_as16Offset4[pstrCodecParams->s16SamplingFreq];
|
2016-11-26 05:09:55 +00:00
|
|
|
} else {
|
2016-11-04 07:08:30 +00:00
|
|
|
ps16GenTabPtr = (SINT16 *)sbc_enc_as16Offset8[pstrCodecParams->s16SamplingFreq];
|
|
|
|
}
|
|
|
|
|
2016-11-26 05:09:55 +00:00
|
|
|
for (s32Sb = 0; s32Sb < s32NumOfSubBands; s32Sb++) {
|
|
|
|
if (*pas16ScaleFactor == 0) {
|
2016-11-04 07:08:30 +00:00
|
|
|
*ps16GenBufPtr = -5;
|
2016-11-26 05:09:55 +00:00
|
|
|
} else {
|
2016-11-04 07:08:30 +00:00
|
|
|
s32Loudness = (SINT32)(*pas16ScaleFactor - *ps16GenTabPtr);
|
|
|
|
|
2016-11-26 05:09:55 +00:00
|
|
|
if (s32Loudness > 0) {
|
2016-11-04 07:08:30 +00:00
|
|
|
*ps16GenBufPtr = (SINT16)(s32Loudness >> 1);
|
2016-11-26 05:09:55 +00:00
|
|
|
} else {
|
2016-11-04 07:08:30 +00:00
|
|
|
*ps16GenBufPtr = (SINT16)s32Loudness;
|
2016-11-26 05:09:55 +00:00
|
|
|
}
|
2016-11-04 07:08:30 +00:00
|
|
|
}
|
|
|
|
|
2016-11-26 05:09:55 +00:00
|
|
|
if (*ps16GenBufPtr > s32MaxBitNeed) {
|
2016-11-04 07:08:30 +00:00
|
|
|
s32MaxBitNeed = *ps16GenBufPtr;
|
2016-11-26 05:09:55 +00:00
|
|
|
}
|
2016-11-04 07:08:30 +00:00
|
|
|
pas16ScaleFactor++;
|
|
|
|
ps16GenBufPtr++;
|
|
|
|
ps16GenTabPtr++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* iterative process to find out hwo many bitslices fit into the bitpool */
|
|
|
|
s32BitSlice = s32MaxBitNeed + 1;
|
|
|
|
s32BitCount = s32BitPool;
|
|
|
|
s32SliceCount = 0;
|
2016-11-26 05:09:55 +00:00
|
|
|
do {
|
2016-11-04 07:08:30 +00:00
|
|
|
s32BitSlice --;
|
|
|
|
s32BitCount -= s32SliceCount;
|
|
|
|
s32SliceCount = 0;
|
|
|
|
ps16GenBufPtr = ps16BitNeed;
|
|
|
|
|
2016-11-26 05:09:55 +00:00
|
|
|
for (s32Sb = 0; s32Sb < 2 * s32NumOfSubBands; s32Sb++) {
|
|
|
|
if ( (*ps16GenBufPtr >= s32BitSlice + 1) && (*ps16GenBufPtr < s32BitSlice + 16) ) {
|
|
|
|
if (*(ps16GenBufPtr) == s32BitSlice + 1) {
|
2016-11-04 07:08:30 +00:00
|
|
|
s32SliceCount += 2;
|
2016-11-26 05:09:55 +00:00
|
|
|
} else {
|
2016-11-04 07:08:30 +00:00
|
|
|
s32SliceCount++;
|
2016-11-26 05:09:55 +00:00
|
|
|
}
|
2016-11-04 07:08:30 +00:00
|
|
|
}
|
|
|
|
ps16GenBufPtr++;
|
|
|
|
}
|
2016-11-26 05:09:55 +00:00
|
|
|
} while (s32BitCount - s32SliceCount > 0);
|
2016-11-04 07:08:30 +00:00
|
|
|
|
2016-11-26 05:09:55 +00:00
|
|
|
if (s32BitCount - s32SliceCount == 0) {
|
2016-11-04 07:08:30 +00:00
|
|
|
s32BitCount -= s32SliceCount;
|
|
|
|
s32BitSlice --;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Bits are distributed until the last bitslice is reached */
|
|
|
|
ps16GenBufPtr = ps16BitNeed;
|
|
|
|
ps16GenArrPtr = pstrCodecParams->as16Bits;
|
2016-11-26 05:09:55 +00:00
|
|
|
for (s32Ch = 0; s32Ch < 2; s32Ch++) {
|
|
|
|
for (s32Sb = 0; s32Sb < s32NumOfSubBands; s32Sb++) {
|
|
|
|
if (*ps16GenBufPtr < s32BitSlice + 2) {
|
2016-11-04 07:08:30 +00:00
|
|
|
*ps16GenArrPtr = 0;
|
2019-03-26 06:37:37 +00:00
|
|
|
} else {
|
2016-11-26 05:09:55 +00:00
|
|
|
*ps16GenArrPtr = ((*(ps16GenBufPtr) - s32BitSlice) < 16) ?
|
|
|
|
(SINT16)(*(ps16GenBufPtr) - s32BitSlice) : 16;
|
2019-03-26 06:37:37 +00:00
|
|
|
}
|
2016-11-04 07:08:30 +00:00
|
|
|
ps16GenBufPtr++;
|
|
|
|
ps16GenArrPtr++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* the remaining bits are allocated starting at subband 0 */
|
2016-11-26 05:09:55 +00:00
|
|
|
s32Ch = 0;
|
|
|
|
s32Sb = 0;
|
2016-11-04 07:08:30 +00:00
|
|
|
ps16GenBufPtr = ps16BitNeed;
|
2016-11-26 05:09:55 +00:00
|
|
|
ps16GenArrPtr -= 2 * s32NumOfSubBands;
|
2016-11-04 07:08:30 +00:00
|
|
|
|
2016-11-26 05:09:55 +00:00
|
|
|
while ( (s32BitCount > 0) && (s32Sb < s32NumOfSubBands) ) {
|
|
|
|
if ( (*(ps16GenArrPtr) >= 2) && (*(ps16GenArrPtr) < 16) ) {
|
2016-11-04 07:08:30 +00:00
|
|
|
(*(ps16GenArrPtr))++;
|
|
|
|
s32BitCount--;
|
2016-11-26 05:09:55 +00:00
|
|
|
} else if ((*ps16GenBufPtr == s32BitSlice + 1) && (s32BitCount > 1)) {
|
2016-11-04 07:08:30 +00:00
|
|
|
*(ps16GenArrPtr) = 2;
|
|
|
|
s32BitCount -= 2;
|
|
|
|
}
|
2016-11-26 05:09:55 +00:00
|
|
|
if (s32Ch == 1) {
|
2016-11-04 07:08:30 +00:00
|
|
|
s32Ch = 0;
|
|
|
|
s32Sb++;
|
2016-11-26 05:09:55 +00:00
|
|
|
ps16GenBufPtr = ps16BitNeed + s32Sb;
|
|
|
|
ps16GenArrPtr = pstrCodecParams->as16Bits + s32Sb;
|
2016-11-04 07:08:30 +00:00
|
|
|
|
2016-11-26 05:09:55 +00:00
|
|
|
} else {
|
|
|
|
s32Ch = 1;
|
|
|
|
ps16GenBufPtr = ps16BitNeed + s32NumOfSubBands + s32Sb;
|
|
|
|
ps16GenArrPtr = pstrCodecParams->as16Bits + s32NumOfSubBands + s32Sb;
|
2016-11-04 07:08:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-26 05:09:55 +00:00
|
|
|
s32Ch = 0;
|
|
|
|
s32Sb = 0;
|
2016-11-04 07:08:30 +00:00
|
|
|
ps16GenArrPtr = pstrCodecParams->as16Bits;
|
|
|
|
|
2016-11-26 05:09:55 +00:00
|
|
|
while ((s32BitCount > 0) && (s32Sb < s32NumOfSubBands)) {
|
|
|
|
if (*(ps16GenArrPtr) < 16) {
|
2016-11-04 07:08:30 +00:00
|
|
|
(*(ps16GenArrPtr))++;
|
|
|
|
s32BitCount--;
|
|
|
|
}
|
2016-11-26 05:09:55 +00:00
|
|
|
if (s32Ch == 1) {
|
2016-11-04 07:08:30 +00:00
|
|
|
s32Ch = 0;
|
|
|
|
s32Sb++;
|
2016-11-26 05:09:55 +00:00
|
|
|
ps16GenArrPtr = pstrCodecParams->as16Bits + s32Sb;
|
|
|
|
} else {
|
2016-11-04 07:08:30 +00:00
|
|
|
s32Ch = 1;
|
2016-11-26 05:09:55 +00:00
|
|
|
ps16GenArrPtr = pstrCodecParams->as16Bits + s32NumOfSubBands + s32Sb;
|
2016-11-04 07:08:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*End of BitAlloc() function*/
|
|
|
|
|
2017-03-17 07:57:30 +00:00
|
|
|
#endif /* #if (defined(SBC_ENC_INCLUDED) && SBC_ENC_INCLUDED == TRUE) */
|