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