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