1ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta/****************************************************************************** 2ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta * 3ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta * Copyright (C) 2014 The Android Open Source Project 49ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * Copyright 2003 - 2004 Open Interface North America, Inc. All rights 59ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson * reserved. 6ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta * 7ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta * Licensed under the Apache License, Version 2.0 (the "License"); 8ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta * you may not use this file except in compliance with the License. 9ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta * You may obtain a copy of the License at: 10ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta * 11ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta * http://www.apache.org/licenses/LICENSE-2.0 12ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta * 13ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta * Unless required by applicable law or agreed to in writing, software 14ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta * distributed under the License is distributed on an "AS IS" BASIS, 15ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta * See the License for the specific language governing permissions and 17ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta * limitations under the License. 18ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta * 19ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta ******************************************************************************/ 20ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta 21ee96a3c60fca590d38025925c072d264e06493c4Myles Watson/******************************************************************************* 22ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta $Revision: #1 $ 23ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/ 24ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta 25ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta/** @file 26ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta@ingroup codec_internal 27ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta*/ 28ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta 29ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta/**@addgroup codec_internal*/ 30ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta/**@{*/ 31ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta 32ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta#include <oi_codec_sbc_private.h> 33ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta 34911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void dualBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT* common) { 35911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson OI_UINT bitcountL; 36911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson OI_UINT bitcountR; 37911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson OI_UINT bitpoolPreferenceL = 0; 38911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson OI_UINT bitpoolPreferenceR = 0; 39911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson BITNEED_UNION1 bitneedsL; 40911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson BITNEED_UNION1 bitneedsR; 41911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 42911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bitcountL = computeBitneed(common, bitneedsL.uint8, 0, &bitpoolPreferenceL); 43911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bitcountR = computeBitneed(common, bitneedsR.uint8, 1, &bitpoolPreferenceR); 44911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 45911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson oneChannelBitAllocation(common, &bitneedsL, 0, bitcountL); 46911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson oneChannelBitAllocation(common, &bitneedsR, 1, bitcountR); 47ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta} 48ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta 49911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void stereoBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT* common) { 50911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson const OI_UINT nrof_subbands = common->frameInfo.nrof_subbands; 51911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson BITNEED_UNION2 bitneeds; 52911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson OI_UINT excess; 53911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson OI_INT bitadjust; 54911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson OI_UINT bitcount; 55911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson OI_UINT sbL; 56911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson OI_UINT sbR; 57911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson OI_UINT bitpoolPreference = 0; 58911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 59911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bitcount = computeBitneed(common, &bitneeds.uint8[0], 0, &bitpoolPreference); 60911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bitcount += computeBitneed(common, &bitneeds.uint8[nrof_subbands], 1, 61911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson &bitpoolPreference); 62911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 63911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson { 64911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson OI_UINT ex; 65911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bitadjust = adjustToFitBitpool(common->frameInfo.bitpool, bitneeds.uint32, 66911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 2 * nrof_subbands, bitcount, &ex); 67911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* We want the compiler to put excess into a register */ 68911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson excess = ex; 69911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 70911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson sbL = 0; 71911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson sbR = nrof_subbands; 72911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson while (sbL < nrof_subbands) { 73911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson excess = allocAdjustedBits(&common->bits.uint8[sbL], 74911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bitneeds.uint8[sbL] + bitadjust, excess); 75911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson ++sbL; 76911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson excess = allocAdjustedBits(&common->bits.uint8[sbR], 77911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bitneeds.uint8[sbR] + bitadjust, excess); 78911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson ++sbR; 79911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 80911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson sbL = 0; 81911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson sbR = nrof_subbands; 82911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson while (excess) { 83911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson excess = allocExcessBits(&common->bits.uint8[sbL], excess); 84911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson ++sbL; 85911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (!excess) { 86911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson break; 87ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta } 88911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson excess = allocExcessBits(&common->bits.uint8[sbR], excess); 89911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson ++sbR; 90911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 91ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta} 92ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta 93ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Guptastatic const BIT_ALLOC balloc[] = { 94911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson monoBitAllocation, /* SBC_MONO */ 95911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson dualBitAllocation, /* SBC_DUAL_CHANNEL */ 96911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson stereoBitAllocation, /* SBC_STEREO */ 97911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson stereoBitAllocation /* SBC_JOINT_STEREO */ 98ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta}; 99ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta 100911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsonPRIVATE void OI_SBC_ComputeBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT* common) { 101911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson OI_ASSERT(common->frameInfo.bitpool <= OI_SBC_MaxBitpool(&common->frameInfo)); 102911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson OI_ASSERT(common->frameInfo.mode < OI_ARRAYSIZE(balloc)); 103ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta 104911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson /* 105911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson * Using an array of function pointers prevents the compiler from creating a 106911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson * suboptimal 107911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson * monolithic inlined bit allocation function. 108911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson */ 109911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson balloc[common->frameInfo.mode](common); 110ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta} 111ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta 112911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint32_t OI_CODEC_SBC_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO* frame) { 113911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return internal_CalculateBitrate(frame); 114ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta} 115ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta 116ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta/* 117ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta * Return the current maximum bitneed and clear it. 118ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta */ 119911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint8_t OI_CODEC_SBC_GetMaxBitneed(OI_CODEC_SBC_COMMON_CONTEXT* common) { 120911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint8_t max = common->maxBitneed; 121ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta 122911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson common->maxBitneed = 0; 123911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return max; 124ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta} 125ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta 126ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta/* 127ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta * Calculates the bitpool size for a given frame length 128ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta */ 129911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint16_t OI_CODEC_SBC_CalculateBitpool(OI_CODEC_SBC_FRAME_INFO* frame, 130911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint16_t frameLen) { 131911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint16_t nrof_subbands = frame->nrof_subbands; 132911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint16_t nrof_blocks = frame->nrof_blocks; 133911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint16_t hdr; 134911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson uint16_t bits; 135911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson 136911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (frame->mode == SBC_JOINT_STEREO) { 137911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson hdr = 9 * nrof_subbands; 138911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } else { 139911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (frame->mode == SBC_MONO) { 140911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson hdr = 4 * nrof_subbands; 141ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta } else { 142911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson hdr = 8 * nrof_subbands; 143911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 144911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson if (frame->mode == SBC_DUAL_CHANNEL) { 145911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson nrof_blocks *= 2; 146ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta } 147911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson } 148911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson bits = 8 * (frameLen - SBC_HEADER_LEN) - hdr; 149911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return DIVIDE(bits, nrof_blocks); 150ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta} 151ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta 152911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint16_t OI_CODEC_SBC_CalculatePcmBytes(OI_CODEC_SBC_COMMON_CONTEXT* common) { 153911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return sizeof(int16_t) * common->pcmStride * common->frameInfo.nrof_subbands * 154911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson common->frameInfo.nrof_blocks; 155ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta} 156ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta 157911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint16_t OI_CODEC_SBC_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO* frame) { 158911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson return internal_CalculateFramelen(frame); 159ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta} 160ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta 161ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta/**@}*/ 162