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 #include "LVM_Types.h"
     19 #include "LVM_Macros.h"
     20 #include "Mixer.h"
     21 #include "LVM_Mixer_FilterCoeffs.h"
     22 
     23 
     24 /************************************************************************/
     25 /* FUNCTION:                                                            */
     26 /*   LVM_Mix_GetTimeConstant                                            */
     27 /*                                                                      */
     28 /* DESCRIPTION:                                                         */
     29 /*  This function calculates the filter coefficient using the following */
     30 /*  equation:                                                           */
     31 /*       Alpha = exp(ln(0.1)/ (tc * Update + 1.0))                      */
     32 /*                                                                      */
     33 /*  This is to be used with the follow first order filter, called at a  */
     34 /*  rate of Update times a second. tc is the required time constant in  */
     35 /*  units of 100us.                                                     */
     36 /*                                                                      */
     37 /*       Output(n) = Alpha * Output(n-1) + (1 - Alpha) * Target(n)      */
     38 /*                                                                      */
     39 /*  The function assumes the block size is large, i.e. the update rate  */
     40 /*  is approximately a fixed, and correct factor of the value of Fs     */
     41 /*  given in the call. This is especially not true when the block size  */
     42 /*  is very small, see the mixer documentation for further details.     */
     43 /*                                                                      */
     44 /*  The function does not support all possible combinations of input    */
     45 /*  values:                                                             */
     46 /*                                                                      */
     47 /*  1. NumChannels is limited to the values 1 (Mono) and 2 (Stereo)     */
     48 /*  2. The product tc * Fs is limited approximately to the range        */
     49 /*      8 < (tc * Fs) < 2^35                                            */
     50 /*                                                                      */
     51 /* PARAMETERS:                                                          */
     52 /*  tc              - the time constant in 100us steps, i.e. 10 = 1ms   */
     53 /*  Fs              - the filter update rate in Hz                      */
     54 /*  NumChannels     - Number of channels 1=Mono, 2=Stereo               */
     55 /*                                                                      */
     56 /* RETURNS:                                                             */
     57 /*  Alpha   - the filter coefficient Q31 format                         */
     58 /*                                                                      */
     59 /************************************************************************/
     60 #ifdef BUILD_FLOAT
     61 LVM_FLOAT LVM_Mixer_TimeConstant(LVM_UINT32   tc,
     62 #ifdef HIGHER_FS
     63                                   LVM_UINT32   Fs,
     64 #else
     65                                   LVM_UINT16   Fs,
     66 #endif
     67                                   LVM_UINT16   NumChannels)
     68 {
     69 
     70     LVM_UINT32  Product;
     71     LVM_FLOAT  ProductFloat;
     72     LVM_INT16   InterpolateShort;
     73     LVM_FLOAT   Interpolate;
     74     LVM_UINT16  Shift;
     75     LVM_FLOAT   Diff;
     76     LVM_FLOAT  Table[] = {ALPHA_Float_0,             /* Log spaced look-up table */
     77                           ALPHA_Float_1,
     78                           ALPHA_Float_2,
     79                           ALPHA_Float_3,
     80                           ALPHA_Float_4,
     81                           ALPHA_Float_5,
     82                           ALPHA_Float_6,
     83                           ALPHA_Float_7,
     84                           ALPHA_Float_8,
     85                           ALPHA_Float_9,
     86                           ALPHA_Float_10,
     87                           ALPHA_Float_11,
     88                           ALPHA_Float_12,
     89                           ALPHA_Float_13,
     90                           ALPHA_Float_14,
     91                           ALPHA_Float_15,
     92                           ALPHA_Float_16,
     93                           ALPHA_Float_17,
     94                           ALPHA_Float_18,
     95                           ALPHA_Float_19,
     96                           ALPHA_Float_20,
     97                           ALPHA_Float_21,
     98                           ALPHA_Float_22,
     99                           ALPHA_Float_23,
    100                           ALPHA_Float_24,
    101                           ALPHA_Float_25,
    102                           ALPHA_Float_26,
    103                           ALPHA_Float_27,
    104                           ALPHA_Float_28,
    105                           ALPHA_Float_29,
    106                           ALPHA_Float_30,
    107                           ALPHA_Float_31,
    108                           ALPHA_Float_32,
    109                           ALPHA_Float_33,
    110                           ALPHA_Float_34,
    111                           ALPHA_Float_35,
    112                           ALPHA_Float_36,
    113                           ALPHA_Float_37,
    114                           ALPHA_Float_38,
    115                           ALPHA_Float_39,
    116                           ALPHA_Float_40,
    117                           ALPHA_Float_41,
    118                           ALPHA_Float_42,
    119                           ALPHA_Float_43,
    120                           ALPHA_Float_44,
    121                           ALPHA_Float_45,
    122                           ALPHA_Float_46,
    123                           ALPHA_Float_47,
    124                           ALPHA_Float_48,
    125                           ALPHA_Float_49,
    126                           ALPHA_Float_50};
    127 
    128     /* Calculate the product of the time constant and the sample rate */
    129     Product = ((tc >> 16) * (LVM_UINT32)Fs) << 13;  /* Stereo value */
    130     Product = Product + (((tc & 0x0000FFFF) * (LVM_UINT32)Fs) >> 3);
    131 
    132     if (NumChannels == 1)
    133     {
    134         Product = Product >> 1;   /* Mono value */
    135     }
    136 
    137     /* Normalize to get the table index and interpolation factor */
    138     for (Shift = 0; Shift < ((Alpha_TableSize - 1) / 2); Shift++)
    139     {
    140         if ((Product & 0x80000000) != 0)
    141         {
    142             break;
    143         }
    144 
    145         Product = Product << 1;
    146     }
    147     Shift = (LVM_UINT16)((Shift << 1));
    148 
    149     if ((Product & 0x40000000)==0)
    150     {
    151         Shift++;
    152     }
    153 
    154     InterpolateShort = (LVM_INT16)((Product >> 15) & 0x00007FFF);
    155     Interpolate = (LVM_FLOAT)InterpolateShort / 32768.0f;
    156 
    157     Diff = (Table[Shift] - Table[Shift + 1]);
    158     Diff = Diff * Interpolate;
    159     ProductFloat = Table[Shift + 1] + Diff;
    160 
    161     return ProductFloat;
    162 }
    163 #else
    164 LVM_UINT32 LVM_Mixer_TimeConstant(LVM_UINT32   tc,
    165                                   LVM_UINT16   Fs,
    166                                   LVM_UINT16   NumChannels)
    167 {
    168 
    169     LVM_UINT32  Product;
    170     LVM_INT16   Interpolate;
    171     LVM_UINT16  Shift;
    172     LVM_INT32   Diff;
    173     LVM_UINT32  Table[] = {ALPHA_0,             /* Log spaced look-up table */
    174                            ALPHA_1,
    175                            ALPHA_2,
    176                            ALPHA_3,
    177                            ALPHA_4,
    178                            ALPHA_5,
    179                            ALPHA_6,
    180                            ALPHA_7,
    181                            ALPHA_8,
    182                            ALPHA_9,
    183                            ALPHA_10,
    184                            ALPHA_11,
    185                            ALPHA_12,
    186                            ALPHA_13,
    187                            ALPHA_14,
    188                            ALPHA_15,
    189                            ALPHA_16,
    190                            ALPHA_17,
    191                            ALPHA_18,
    192                            ALPHA_19,
    193                            ALPHA_20,
    194                            ALPHA_21,
    195                            ALPHA_22,
    196                            ALPHA_23,
    197                            ALPHA_24,
    198                            ALPHA_25,
    199                            ALPHA_26,
    200                            ALPHA_27,
    201                            ALPHA_28,
    202                            ALPHA_29,
    203                            ALPHA_30,
    204                            ALPHA_31,
    205                            ALPHA_32,
    206                            ALPHA_33,
    207                            ALPHA_34,
    208                            ALPHA_35,
    209                            ALPHA_36,
    210                            ALPHA_37,
    211                            ALPHA_38,
    212                            ALPHA_39,
    213                            ALPHA_40,
    214                            ALPHA_41,
    215                            ALPHA_42,
    216                            ALPHA_43,
    217                            ALPHA_44,
    218                            ALPHA_45,
    219                            ALPHA_46,
    220                            ALPHA_47,
    221                            ALPHA_48,
    222                            ALPHA_49,
    223                            ALPHA_50};
    224 
    225 
    226     /* Calculate the product of the time constant and the sample rate */
    227     Product = ((tc >> 16) * (LVM_UINT32)Fs) << 13;  /* Stereo value */
    228     Product = Product + (((tc & 0x0000FFFF) * (LVM_UINT32)Fs) >> 3);
    229 
    230     if (NumChannels == 1)
    231     {
    232         Product = Product >> 1;   /* Mono value */
    233     }
    234 
    235     /* Normalize to get the table index and interpolation factor */
    236     for (Shift=0; Shift<((Alpha_TableSize-1)/2); Shift++)
    237     {
    238         if ((Product & 0x80000000)!=0)
    239         {
    240             break;
    241         }
    242 
    243         Product = Product << 1;
    244     }
    245     Shift = (LVM_UINT16)((Shift << 1));
    246 
    247     if ((Product & 0x40000000)==0)
    248     {
    249         Shift++;
    250     }
    251 
    252     Interpolate = (LVM_INT16)((Product >> 15) & 0x00007FFF);
    253 
    254     Diff = (LVM_INT32)(Table[Shift] - Table[Shift+1]);
    255     MUL32x16INTO32(Diff,Interpolate,Diff,15)
    256         Product = Table[Shift+1] + (LVM_UINT32)Diff;
    257 
    258     return Product;
    259 }
    260 #endif
    261