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 #include "common/bt_target.h"
31 #include <oi_codec_sbc_private.h>
32
33 #if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE)
34
dualBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT * common)35 static void dualBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common)
36 {
37 OI_UINT bitcountL;
38 OI_UINT bitcountR;
39 OI_UINT bitpoolPreferenceL = 0;
40 OI_UINT bitpoolPreferenceR = 0;
41 BITNEED_UNION1 bitneedsL;
42 BITNEED_UNION1 bitneedsR;
43
44 bitcountL = computeBitneed(common, bitneedsL.uint8, 0, &bitpoolPreferenceL);
45 bitcountR = computeBitneed(common, bitneedsR.uint8, 1, &bitpoolPreferenceR);
46
47 oneChannelBitAllocation(common, &bitneedsL, 0, bitcountL);
48 oneChannelBitAllocation(common, &bitneedsR, 1, bitcountR);
49 }
50
stereoBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT * common)51 static void stereoBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common)
52 {
53 const OI_UINT nrof_subbands = common->frameInfo.nrof_subbands;
54 BITNEED_UNION2 bitneeds;
55 OI_UINT excess;
56 OI_INT bitadjust;
57 OI_UINT bitcount;
58 OI_UINT sbL;
59 OI_UINT sbR;
60 OI_UINT bitpoolPreference = 0;
61
62 bitcount = computeBitneed(common, &bitneeds.uint8[0], 0, &bitpoolPreference);
63 bitcount += computeBitneed(common, &bitneeds.uint8[nrof_subbands], 1, &bitpoolPreference);
64
65 {
66 OI_UINT ex;
67 bitadjust = adjustToFitBitpool(common->frameInfo.bitpool, bitneeds.uint32, 2 * nrof_subbands, bitcount, &ex);
68 /* We want the compiler to put excess into a register */
69 excess = ex;
70 }
71 sbL = 0;
72 sbR = nrof_subbands;
73 while (sbL < nrof_subbands) {
74 excess = allocAdjustedBits(&common->bits.uint8[sbL], bitneeds.uint8[sbL] + bitadjust, excess);
75 ++sbL;
76 excess = allocAdjustedBits(&common->bits.uint8[sbR], bitneeds.uint8[sbR] + bitadjust, excess);
77 ++sbR;
78 }
79 sbL = 0;
80 sbR = nrof_subbands;
81 while (excess) {
82 excess = allocExcessBits(&common->bits.uint8[sbL], excess);
83 ++sbL;
84 if (!excess) {
85 break;
86 }
87 excess = allocExcessBits(&common->bits.uint8[sbR], excess);
88 ++sbR;
89 }
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
OI_SBC_ComputeBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT * common)101 PRIVATE void OI_SBC_ComputeBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT *common)
102 {
103 OI_ASSERT(common->frameInfo.bitpool <= OI_SBC_MaxBitpool(&common->frameInfo));
104 OI_ASSERT(common->frameInfo.mode < OI_ARRAYSIZE(balloc));
105
106 /*
107 * Using an array of function pointers prevents the compiler from creating a suboptimal
108 * monolithic inlined bit allocation function.
109 */
110 balloc[common->frameInfo.mode](common);
111 }
112
OI_CODEC_SBC_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO * frame)113 OI_UINT32 OI_CODEC_SBC_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO *frame)
114 {
115 return internal_CalculateBitrate(frame);
116 }
117
118 /*
119 * Return the current maximum bitneed and clear it.
120 */
OI_CODEC_SBC_GetMaxBitneed(OI_CODEC_SBC_COMMON_CONTEXT * common)121 OI_UINT8 OI_CODEC_SBC_GetMaxBitneed(OI_CODEC_SBC_COMMON_CONTEXT *common)
122 {
123 OI_UINT8 max = common->maxBitneed;
124
125 common->maxBitneed = 0;
126 return max;
127 }
128
129 /*
130 * Calculates the bitpool size for a given frame length
131 */
OI_CODEC_SBC_CalculateBitpool(OI_CODEC_SBC_FRAME_INFO * frame,OI_UINT16 frameLen)132 OI_UINT16 OI_CODEC_SBC_CalculateBitpool(OI_CODEC_SBC_FRAME_INFO *frame,
133 OI_UINT16 frameLen)
134 {
135 OI_UINT16 nrof_subbands = frame->nrof_subbands;
136 OI_UINT16 nrof_blocks = frame->nrof_blocks;
137 OI_UINT16 hdr;
138 OI_UINT16 bits;
139
140 if (frame->mode == SBC_JOINT_STEREO) {
141 hdr = 9 * nrof_subbands;
142 } else {
143 if (frame->mode == SBC_MONO) {
144 hdr = 4 * nrof_subbands;
145 } else {
146 hdr = 8 * nrof_subbands;
147 }
148 if (frame->mode == SBC_DUAL_CHANNEL) {
149 nrof_blocks *= 2;
150 }
151 }
152 bits = 8 * (frameLen - SBC_HEADER_LEN) - hdr;
153 return DIVIDE(bits, nrof_blocks);
154 }
155
OI_CODEC_SBC_CalculatePcmBytes(OI_CODEC_SBC_COMMON_CONTEXT * common)156 OI_UINT16 OI_CODEC_SBC_CalculatePcmBytes(OI_CODEC_SBC_COMMON_CONTEXT *common)
157 {
158 return sizeof(OI_INT16) * common->pcmStride * common->frameInfo.nrof_subbands * common->frameInfo.nrof_blocks;
159 }
160
161
OI_CODEC_SBC_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO * frame)162 OI_UINT16 OI_CODEC_SBC_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO *frame)
163 {
164 return internal_CalculateFramelen(frame);
165 }
166
167 /**@}*/
168 #endif /* #if (defined(SBC_DEC_INCLUDED) && SBC_DEC_INCLUDED == TRUE) */
169