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