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