1ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta/******************************************************************************
2ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta *
3ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta *  Copyright (C) 2014 The Android Open Source Project
49ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *  Copyright 2003 - 2004 Open Interface North America, Inc. All rights
59ca07091a1f07ea201cee0504dab6a1d7073d429Myles Watson *                        reserved.
6ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta *
7ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta *  Licensed under the Apache License, Version 2.0 (the "License");
8ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta *  you may not use this file except in compliance with the License.
9ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta *  You may obtain a copy of the License at:
10ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta *
11ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta *  http://www.apache.org/licenses/LICENSE-2.0
12ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta *
13ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta *  Unless required by applicable law or agreed to in writing, software
14ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta *  distributed under the License is distributed on an "AS IS" BASIS,
15ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta *  See the License for the specific language governing permissions and
17ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta *  limitations under the License.
18ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta *
19ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta ******************************************************************************/
20ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta
21ee96a3c60fca590d38025925c072d264e06493c4Myles Watson/*******************************************************************************
22ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta  $Revision: #1 $
23ee96a3c60fca590d38025925c072d264e06493c4Myles Watson ******************************************************************************/
24ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta
25ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta/** @file
26ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta@ingroup codec_internal
27ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta*/
28ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta
29ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta/**@addgroup codec_internal*/
30ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta/**@{*/
31ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta
32ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta#include <oi_codec_sbc_private.h>
33ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta
34911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void dualBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT* common) {
35911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  OI_UINT bitcountL;
36911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  OI_UINT bitcountR;
37911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  OI_UINT bitpoolPreferenceL = 0;
38911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  OI_UINT bitpoolPreferenceR = 0;
39911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BITNEED_UNION1 bitneedsL;
40911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BITNEED_UNION1 bitneedsR;
41911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
42911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bitcountL = computeBitneed(common, bitneedsL.uint8, 0, &bitpoolPreferenceL);
43911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bitcountR = computeBitneed(common, bitneedsR.uint8, 1, &bitpoolPreferenceR);
44911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
45911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  oneChannelBitAllocation(common, &bitneedsL, 0, bitcountL);
46911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  oneChannelBitAllocation(common, &bitneedsR, 1, bitcountR);
47ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta}
48ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta
49911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonstatic void stereoBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT* common) {
50911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  const OI_UINT nrof_subbands = common->frameInfo.nrof_subbands;
51911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  BITNEED_UNION2 bitneeds;
52911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  OI_UINT excess;
53911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  OI_INT bitadjust;
54911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  OI_UINT bitcount;
55911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  OI_UINT sbL;
56911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  OI_UINT sbR;
57911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  OI_UINT bitpoolPreference = 0;
58911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
59911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bitcount = computeBitneed(common, &bitneeds.uint8[0], 0, &bitpoolPreference);
60911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bitcount += computeBitneed(common, &bitneeds.uint8[nrof_subbands], 1,
61911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                             &bitpoolPreference);
62911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
63911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  {
64911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    OI_UINT ex;
65911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    bitadjust = adjustToFitBitpool(common->frameInfo.bitpool, bitneeds.uint32,
66911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                   2 * nrof_subbands, bitcount, &ex);
67911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    /* We want the compiler to put excess into a register */
68911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    excess = ex;
69911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
70911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  sbL = 0;
71911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  sbR = nrof_subbands;
72911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  while (sbL < nrof_subbands) {
73911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    excess = allocAdjustedBits(&common->bits.uint8[sbL],
74911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                               bitneeds.uint8[sbL] + bitadjust, excess);
75911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    ++sbL;
76911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    excess = allocAdjustedBits(&common->bits.uint8[sbR],
77911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                               bitneeds.uint8[sbR] + bitadjust, excess);
78911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    ++sbR;
79911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
80911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  sbL = 0;
81911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  sbR = nrof_subbands;
82911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  while (excess) {
83911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    excess = allocExcessBits(&common->bits.uint8[sbL], excess);
84911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    ++sbL;
85911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (!excess) {
86911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      break;
87ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta    }
88911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    excess = allocExcessBits(&common->bits.uint8[sbR], excess);
89911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    ++sbR;
90911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
91ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta}
92ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta
93ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Guptastatic const BIT_ALLOC balloc[] = {
94911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    monoBitAllocation,   /* SBC_MONO */
95911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    dualBitAllocation,   /* SBC_DUAL_CHANNEL */
96911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    stereoBitAllocation, /* SBC_STEREO */
97911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    stereoBitAllocation  /* SBC_JOINT_STEREO */
98ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta};
99ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta
100911d1ae03efec2d54c3b1b605589d790d1745488Myles WatsonPRIVATE void OI_SBC_ComputeBitAllocation(OI_CODEC_SBC_COMMON_CONTEXT* common) {
101911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  OI_ASSERT(common->frameInfo.bitpool <= OI_SBC_MaxBitpool(&common->frameInfo));
102911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  OI_ASSERT(common->frameInfo.mode < OI_ARRAYSIZE(balloc));
103ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta
104911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  /*
105911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson   * Using an array of function pointers prevents the compiler from creating a
106911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson   * suboptimal
107911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson   * monolithic inlined bit allocation function.
108911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson   */
109911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  balloc[common->frameInfo.mode](common);
110ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta}
111ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta
112911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint32_t OI_CODEC_SBC_CalculateBitrate(OI_CODEC_SBC_FRAME_INFO* frame) {
113911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return internal_CalculateBitrate(frame);
114ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta}
115ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta
116ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta/*
117ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta * Return the current maximum bitneed and clear it.
118ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta */
119911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint8_t OI_CODEC_SBC_GetMaxBitneed(OI_CODEC_SBC_COMMON_CONTEXT* common) {
120911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint8_t max = common->maxBitneed;
121ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta
122911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  common->maxBitneed = 0;
123911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return max;
124ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta}
125ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta
126ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta/*
127ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta * Calculates the bitpool size for a given frame length
128ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta */
129911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint16_t OI_CODEC_SBC_CalculateBitpool(OI_CODEC_SBC_FRAME_INFO* frame,
130911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson                                       uint16_t frameLen) {
131911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t nrof_subbands = frame->nrof_subbands;
132911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t nrof_blocks = frame->nrof_blocks;
133911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t hdr;
134911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  uint16_t bits;
135911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson
136911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  if (frame->mode == SBC_JOINT_STEREO) {
137911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    hdr = 9 * nrof_subbands;
138911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  } else {
139911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (frame->mode == SBC_MONO) {
140911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      hdr = 4 * nrof_subbands;
141ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta    } else {
142911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      hdr = 8 * nrof_subbands;
143911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    }
144911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson    if (frame->mode == SBC_DUAL_CHANNEL) {
145911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson      nrof_blocks *= 2;
146ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta    }
147911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  }
148911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  bits = 8 * (frameLen - SBC_HEADER_LEN) - hdr;
149911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return DIVIDE(bits, nrof_blocks);
150ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta}
151ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta
152911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint16_t OI_CODEC_SBC_CalculatePcmBytes(OI_CODEC_SBC_COMMON_CONTEXT* common) {
153911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return sizeof(int16_t) * common->pcmStride * common->frameInfo.nrof_subbands *
154911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson         common->frameInfo.nrof_blocks;
155ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta}
156ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta
157911d1ae03efec2d54c3b1b605589d790d1745488Myles Watsonuint16_t OI_CODEC_SBC_CalculateFramelen(OI_CODEC_SBC_FRAME_INFO* frame) {
158911d1ae03efec2d54c3b1b605589d790d1745488Myles Watson  return internal_CalculateFramelen(frame);
159ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta}
160ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta
161ce24765fe7620c34e8d88ed4f826c8a6917582b2Hemant Gupta/**@}*/
162