Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2004-2010 NXP Software
      3  * Copyright (C) 2010 The Android Open Source Project
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 /************************************************************************/
     19 /*                                                                      */
     20 /*     %created_by:    sra % (CM/S)*/
     21 /*     %name:          dB_to_Lin32.c % (CM/S)*/
     22 /*     %version:       2 % (CM/S)*/
     23 /*     %date_created:  Wed Jun 18 11:27:46 2008 % (CM/S)*/
     24 /*                                                                      */
     25 /************************************************************************/
     26 
     27 /*######################################################################################*/
     28 /*  Include files                                                                       */
     29 /*######################################################################################*/
     30 
     31 #include "ScalarArithmetic.h"
     32 
     33 
     34 /****************************************************************************************
     35  *  Name        : dB_to_Lin32()
     36  *  Input       : Signed 16-bit integer
     37  *                  MSB (16) = sign bit
     38  *                  (15->05) = integer part
     39  *                  (04->01) = decimal part
     40  *  Output      : Signed 32-bit integer
     41  *                  MSB (32) = sign bit
     42  *                  (31->16) = integer part
     43  *                  (15->01) = decimal part
     44  *  Returns     : Lin value format 1.16.15
     45  *  Description :
     46  *  Remarks     :  Makes an approximation to the conversion by counting the number
     47  *                 of 6dB steps for use as shifts and then interpolates with a remainder
     48  *                 with the equation:
     49  *
     50  *                 Correction = (Remainder / 1.5029) - (Remainder^2 / 6)
     51  *
     52  *                 The two coefficients are scaled from 0x40000000 in 96 steps and calculated
     53  *                 as follows:
     54  *
     55  *                 FIRST_COEF  = 0x80000000 / (96 * 1.5029)
     56  *                 SECOND_COEF = 0x80000000 / (96^2 * 6)
     57  *
     58  ****************************************************************************************/
     59 
     60 #define FOUR_OVER_SIX    21846                  /* (4 / 6) * 2^15 */
     61 #define SIX_DB           96                     /* 6 * 16 or 6dB in Q11.4 format */
     62 #define FIRST_COEF_NEG   14884305
     63 #define FIRST_COEF_POS   7442152                /* FIRST_COEF_NEG / 2 */
     64 #define SECOND_COEF      38836
     65 #define MAX_VALUE        1536                   /* 96 * 16 */
     66 
     67 LVM_INT32   dB_to_Lin32(LVM_INT16    db_fix)
     68 {
     69     LVM_INT32 Lin_val_32;
     70     LVM_INT16 Shift;
     71     LVM_INT32 Remain;
     72 
     73 
     74     /*
     75      * Check sign of the input
     76      */
     77     if (db_fix<0)
     78     {
     79         if (db_fix > -MAX_VALUE)
     80         {
     81             Shift  = (LVM_INT16)((((LVM_UINT32)(-db_fix) >> 4) * FOUR_OVER_SIX) >> 17);        /* Number of 6dB steps in Q11.4 format */
     82             Remain = -db_fix - (Shift * SIX_DB);
     83             Remain = (0x7FFFFFFF - (Remain * FIRST_COEF_NEG)) + (Remain * Remain * SECOND_COEF);
     84             Lin_val_32 = (LVM_INT32)((LVM_UINT32)Remain >> (16 + Shift));
     85         }
     86         else
     87         {
     88             Lin_val_32 = 0;
     89         }
     90     }
     91     else
     92     {
     93         if (db_fix < MAX_VALUE)
     94         {
     95             Shift  = (LVM_INT16)((((LVM_UINT32)db_fix >> 4) * FOUR_OVER_SIX) >> 17);        /* Number of 6dB steps in Q11.4 format */
     96             Remain = db_fix - (Shift * SIX_DB);
     97             Remain = 0x3FFFFFFF + (Remain * FIRST_COEF_POS) + (Remain * Remain * SECOND_COEF);
     98             Lin_val_32 = (LVM_INT32)((LVM_UINT32)Remain >> (15 - Shift));
     99         }
    100         else
    101         {
    102             Lin_val_32 = 0x7FFFFFFF;
    103         }
    104     }
    105 
    106 
    107     return Lin_val_32;  /* format 1.16.15 */
    108 }
    109 
    110