1 /****************************************************************************** 2 * 3 * Copyright (C) 2014 The Android Open Source Project 4 * Copyright 2003 - 2004 Open Interface North America, Inc. All rights 5 * reserved. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at: 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 ******************************************************************************/ 20 21 /******************************************************************************* 22 $Revision: #1 $ 23 ******************************************************************************/ 24 25 /** @file 26 @ingroup codec_internal 27 */ 28 29 /**@addgroup codec_internal*/ 30 /**@{*/ 31 32 #include <oi_codec_sbc_private.h> 33 34 static void dualBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT* common) { 35 OI_UINT bitcountL; 36 OI_UINT bitcountR; 37 OI_UINT bitpoolPreferenceL = 0; 38 OI_UINT bitpoolPreferenceR = 0; 39 BITNEED_UNION1 bitneedsL; 40 BITNEED_UNION1 bitneedsR; 41 42 bitcountL = computeBitneed(common, bitneedsL.uint8, 0, &bitpoolPreferenceL); 43 bitcountR = computeBitneed(common, bitneedsR.uint8, 1, &bitpoolPreferenceR); 44 45 oneChannelBitAllocation(common, &bitneedsL, 0, bitcountL); 46 oneChannelBitAllocation(common, &bitneedsR, 1, bitcountR); 47 } 48 49 static void stereoBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT* common) { 50 const OI_UINT nrof_subbands = common->frameInfo.nrof_subbands; 51 BITNEED_UNION2 bitneeds; 52 OI_UINT excess; 53 OI_INT bitadjust; 54 OI_UINT bitcount; 55 OI_UINT sbL; 56 OI_UINT sbR; 57 OI_UINT bitpoolPreference = 0; 58 59 bitcount = computeBitneed(common, &bitneeds.uint8[0], 0, &bitpoolPreference); 60 bitcount += computeBitneed(common, &bitneeds.uint8[nrof_subbands], 1, 61 &bitpoolPreference); 62 63 { 64 OI_UINT ex; 65 bitadjust = adjustToFitBitpool(common->frameInfo.bitpool, bitneeds.uint32, 66 2 * nrof_subbands, bitcount, &ex); 67 /* We want the compiler to put excess into a register */ 68 excess = ex; 69 } 70 sbL = 0; 71 sbR = nrof_subbands; 72 while (sbL < nrof_subbands) { 73 excess = allocAdjustedBits(&common->bits.uint8[sbL], 74 bitneeds.uint8[sbL] + bitadjust, excess); 75 ++sbL; 76 excess = allocAdjustedBits(&common->bits.uint8[sbR], 77 bitneeds.uint8[sbR] + bitadjust, excess); 78 ++sbR; 79 } 80 sbL = 0; 81 sbR = nrof_subbands; 82 while (excess) { 83 excess = allocExcessBits(&common->bits.uint8[sbL], excess); 84 ++sbL; 85 if (!excess) { 86 break; 87 } 88 excess = allocExcessBits(&common->bits.uint8[sbR], excess); 89 ++sbR; 90 } 91 } 92 93 static const BIT_ALLOC balloc[] = { 94 monoBitAllocation, /* SBC_MONO */ 95 dualBitAllocation, /* SBC_DUAL_CHANNEL */ 96 stereoBitAllocation, /* SBC_STEREO */ 97 stereoBitAllocation /* SBC_JOINT_STEREO */ 98 }; 99 100 PRIVATE void OI_SBC_ComputeBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT* common) { 101 OI_ASSERT(common->frameInfo.bitpool <= OI_SBC_MaxBitpool(&common->frameInfo)); 102 OI_ASSERT(common->frameInfo.mode < OI_ARRAYSIZE(balloc)); 103 104 /* 105 * Using an array of function pointers prevents the compiler from creating a 106 * suboptimal 107 * monolithic inlined bit allocation function. 108 */ 109 balloc[common->frameInfo.mode](common); 110 } 111 112 uint32_t OI_CODEC_SBC_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO* frame) { 113 return internal_CalculateBitrate(frame); 114 } 115 116 /* 117 * Return the current maximum bitneed and clear it. 118 */ 119 uint8_t OI_CODEC_SBC_GetMaxBitneed(OI_CODEC_SBC_COMMON_CONTEXT* common) { 120 uint8_t max = common->maxBitneed; 121 122 common->maxBitneed = 0; 123 return max; 124 } 125 126 /* 127 * Calculates the bitpool size for a given frame length 128 */ 129 uint16_t OI_CODEC_SBC_CalculateBitpool(OI_CODEC_SBC_FRAME_INFO* frame, 130 uint16_t frameLen) { 131 uint16_t nrof_subbands = frame->nrof_subbands; 132 uint16_t nrof_blocks = frame->nrof_blocks; 133 uint16_t hdr; 134 uint16_t bits; 135 136 if (frame->mode == SBC_JOINT_STEREO) { 137 hdr = 9 * nrof_subbands; 138 } else { 139 if (frame->mode == SBC_MONO) { 140 hdr = 4 * nrof_subbands; 141 } else { 142 hdr = 8 * nrof_subbands; 143 } 144 if (frame->mode == SBC_DUAL_CHANNEL) { 145 nrof_blocks *= 2; 146 } 147 } 148 bits = 8 * (frameLen - SBC_HEADER_LEN) - hdr; 149 return DIVIDE(bits, nrof_blocks); 150 } 151 152 uint16_t OI_CODEC_SBC_CalculatePcmBytes(OI_CODEC_SBC_COMMON_CONTEXT* common) { 153 return sizeof(int16_t) * common->pcmStride * common->frameInfo.nrof_subbands * 154 common->frameInfo.nrof_blocks; 155 } 156 157 uint16_t OI_CODEC_SBC_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO* frame) { 158 return internal_CalculateFramelen(frame); 159 } 160 161 /**@}*/ 162