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