| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- /******************************************************************************
- *
- * Copyright (C) 2014 The Android Open Source Project
- * Copyright 2003 - 2004 Open Interface North America, Inc. All rights reserved.
- *
- * 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.
- *
- ******************************************************************************/
- /**********************************************************************************
- $Revision: #1 $
- ***********************************************************************************/
- /** @file
- @ingroup codec_internal
- */
- /**@addgroup codec_internal*/
- /**@{*/
- #include "common/bt_target.h"
- #include <oi_codec_sbc_private.h>
- #if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE)
- static void dualBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common)
- {
- OI_UINT bitcountL;
- OI_UINT bitcountR;
- OI_UINT bitpoolPreferenceL = 0;
- OI_UINT bitpoolPreferenceR = 0;
- BITNEED_UNION1 bitneedsL;
- BITNEED_UNION1 bitneedsR;
- bitcountL = computeBitneed(common, bitneedsL.uint8, 0, &bitpoolPreferenceL);
- bitcountR = computeBitneed(common, bitneedsR.uint8, 1, &bitpoolPreferenceR);
- oneChannelBitAllocation(common, &bitneedsL, 0, bitcountL);
- oneChannelBitAllocation(common, &bitneedsR, 1, bitcountR);
- }
- static void stereoBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common)
- {
- const OI_UINT nrof_subbands = common->frameInfo.nrof_subbands;
- BITNEED_UNION2 bitneeds;
- OI_UINT excess;
- OI_INT bitadjust;
- OI_UINT bitcount;
- OI_UINT sbL;
- OI_UINT sbR;
- OI_UINT bitpoolPreference = 0;
- bitcount = computeBitneed(common, &bitneeds.uint8[0], 0, &bitpoolPreference);
- bitcount += computeBitneed(common, &bitneeds.uint8[nrof_subbands], 1, &bitpoolPreference);
- {
- OI_UINT ex;
- bitadjust = adjustToFitBitpool(common->frameInfo.bitpool, bitneeds.uint32, 2 * nrof_subbands, bitcount, &ex);
- /* We want the compiler to put excess into a register */
- excess = ex;
- }
- sbL = 0;
- sbR = nrof_subbands;
- while (sbL < nrof_subbands) {
- excess = allocAdjustedBits(&common->bits.uint8[sbL], bitneeds.uint8[sbL] + bitadjust, excess);
- ++sbL;
- excess = allocAdjustedBits(&common->bits.uint8[sbR], bitneeds.uint8[sbR] + bitadjust, excess);
- ++sbR;
- }
- sbL = 0;
- sbR = nrof_subbands;
- while (excess) {
- excess = allocExcessBits(&common->bits.uint8[sbL], excess);
- ++sbL;
- if (!excess) {
- break;
- }
- excess = allocExcessBits(&common->bits.uint8[sbR], excess);
- ++sbR;
- }
- }
- static const BIT_ALLOC balloc[] = {
- monoBitAllocation, /* SBC_MONO */
- dualBitAllocation, /* SBC_DUAL_CHANNEL */
- stereoBitAllocation, /* SBC_STEREO */
- stereoBitAllocation /* SBC_JOINT_STEREO */
- };
- PRIVATE void OI_SBC_ComputeBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common)
- {
- OI_ASSERT(common->frameInfo.bitpool <= OI_SBC_MaxBitpool(&common->frameInfo));
- OI_ASSERT(common->frameInfo.mode < OI_ARRAYSIZE(balloc));
- /*
- * Using an array of function pointers prevents the compiler from creating a suboptimal
- * monolithic inlined bit allocation function.
- */
- balloc[common->frameInfo.mode](common);
- }
- OI_UINT32 OI_CODEC_SBC_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO *frame)
- {
- return internal_CalculateBitrate(frame);
- }
- /*
- * Return the current maximum bitneed and clear it.
- */
- OI_UINT8 OI_CODEC_SBC_GetMaxBitneed(OI_CODEC_SBC_COMMON_CONTEXT *common)
- {
- OI_UINT8 max = common->maxBitneed;
- common->maxBitneed = 0;
- return max;
- }
- /*
- * Calculates the bitpool size for a given frame length
- */
- OI_UINT16 OI_CODEC_SBC_CalculateBitpool(OI_CODEC_SBC_FRAME_INFO *frame,
- OI_UINT16 frameLen)
- {
- OI_UINT16 nrof_subbands = frame->nrof_subbands;
- OI_UINT16 nrof_blocks = frame->nrof_blocks;
- OI_UINT16 hdr;
- OI_UINT16 bits;
- if (frame->mode == SBC_JOINT_STEREO) {
- hdr = 9 * nrof_subbands;
- } else {
- if (frame->mode == SBC_MONO) {
- hdr = 4 * nrof_subbands;
- } else {
- hdr = 8 * nrof_subbands;
- }
- if (frame->mode == SBC_DUAL_CHANNEL) {
- nrof_blocks *= 2;
- }
- }
- bits = 8 * (frameLen - SBC_HEADER_LEN) - hdr;
- return DIVIDE(bits, nrof_blocks);
- }
- OI_UINT16 OI_CODEC_SBC_CalculatePcmBytes(OI_CODEC_SBC_COMMON_CONTEXT *common)
- {
- return sizeof(OI_INT16) * common->pcmStride * common->frameInfo.nrof_subbands * common->frameInfo.nrof_blocks;
- }
- OI_UINT16 OI_CODEC_SBC_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO *frame)
- {
- return internal_CalculateFramelen(frame);
- }
- /**@}*/
- #endif /* #if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE) */
|