LVM_Mixer_TimeConstant.c revision 2c8e5cab3faa6d360e222b7a6c40a80083d021ac
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/*     Project::                                                        */
21/*     $Author: beq07716 $*/
22/*     $Revision: 1000 $*/
23/*     $Date: 2010-06-28 13:08:20 +0200 (Mon, 28 Jun 2010) $*/
24/*                                                                      */
25/************************************************************************/
26
27#include "LVM_Types.h"
28#include "LVM_Macros.h"
29#include "Mixer.h"
30#include "LVM_Mixer_FilterCoeffs.h"
31
32
33/************************************************************************/
34/* FUNCTION:                                                            */
35/*   LVM_Mix_GetTimeConstant                                            */
36/*                                                                      */
37/* DESCRIPTION:                                                         */
38/*  This function calculates the filter coefficient using the following */
39/*  equation:                                                           */
40/*       Alpha = exp(ln(0.1)/ (tc * Update + 1.0))                      */
41/*                                                                      */
42/*  This is to be used with the follow first order filter, called at a  */
43/*  rate of Update times a second. tc is the required time constant in  */
44/*  units of 100us.                                                     */
45/*                                                                      */
46/*       Output(n) = Alpha * Output(n-1) + (1 - Alpha) * Target(n)      */
47/*                                                                      */
48/*  The function assumes the block size is large, i.e. the update rate  */
49/*  is approximately a fixed, and correct factor of the value of Fs     */
50/*  given in the call. This is especially not true when the block size  */
51/*  is very small, see the mixer documentation for further details.     */
52/*                                                                      */
53/*  The function does not support all possible combinations of input    */
54/*  values:                                                             */
55/*                                                                      */
56/*  1. NumChannels is limited to the values 1 (Mono) and 2 (Stereo)     */
57/*  2. The product tc * Fs is limited approximately to the range        */
58/*      8 < (tc * Fs) < 2^35                                            */
59/*                                                                      */
60/* PARAMETERS:                                                          */
61/*  tc              - the time constant in 100us steps, i.e. 10 = 1ms   */
62/*  Fs              - the filter update rate in Hz                      */
63/*  NumChannels     - Number of channels 1=Mono, 2=Stereo               */
64/*                                                                      */
65/* RETURNS:                                                             */
66/*  Alpha   - the filter coefficient Q31 format                         */
67/*                                                                      */
68/************************************************************************/
69
70LVM_UINT32 LVM_Mixer_TimeConstant(LVM_UINT32   tc,
71                                  LVM_UINT16   Fs,
72                                  LVM_UINT16   NumChannels)
73{
74
75    LVM_UINT32  Product;
76    LVM_INT16   Interpolate;
77    LVM_UINT16  Shift;
78    LVM_INT32   Diff;
79    LVM_UINT32  Table[] = {ALPHA_0,             /* Log spaced look-up table */
80                           ALPHA_1,
81                           ALPHA_2,
82                           ALPHA_3,
83                           ALPHA_4,
84                           ALPHA_5,
85                           ALPHA_6,
86                           ALPHA_7,
87                           ALPHA_8,
88                           ALPHA_9,
89                           ALPHA_10,
90                           ALPHA_11,
91                           ALPHA_12,
92                           ALPHA_13,
93                           ALPHA_14,
94                           ALPHA_15,
95                           ALPHA_16,
96                           ALPHA_17,
97                           ALPHA_18,
98                           ALPHA_19,
99                           ALPHA_20,
100                           ALPHA_21,
101                           ALPHA_22,
102                           ALPHA_23,
103                           ALPHA_24,
104                           ALPHA_25,
105                           ALPHA_26,
106                           ALPHA_27,
107                           ALPHA_28,
108                           ALPHA_29,
109                           ALPHA_30,
110                           ALPHA_31,
111                           ALPHA_32,
112                           ALPHA_33,
113                           ALPHA_34,
114                           ALPHA_35,
115                           ALPHA_36,
116                           ALPHA_37,
117                           ALPHA_38,
118                           ALPHA_39,
119                           ALPHA_40,
120                           ALPHA_41,
121                           ALPHA_42,
122                           ALPHA_43,
123                           ALPHA_44,
124                           ALPHA_45,
125                           ALPHA_46,
126                           ALPHA_47,
127                           ALPHA_48,
128                           ALPHA_49,
129                           ALPHA_50};
130
131
132    /* Calculate the product of the time constant and the sample rate */
133    Product = ((tc >> 16) * (LVM_UINT32)Fs) << 13;  /* Stereo value */
134    Product = Product + (((tc & 0x0000FFFF) * (LVM_UINT32)Fs) >> 3);
135
136    if (NumChannels == 1)
137    {
138        Product = Product >> 1;   /* Mono value */
139    }
140
141    /* Normalize to get the table index and interpolation factor */
142    for (Shift=0; Shift<((Alpha_TableSize-1)/2); Shift++)
143    {
144        if ((Product & 0x80000000)!=0)
145        {
146            break;
147        }
148
149        Product = Product << 1;
150    }
151    Shift = (LVM_UINT16)((Shift << 1));
152
153    if ((Product & 0x40000000)==0)
154    {
155        Shift++;
156    }
157
158    Interpolate = (LVM_INT16)((Product >> 15) & 0x00007FFF);
159
160    Diff = (LVM_INT32)(Table[Shift] - Table[Shift+1]);
161    MUL32x16INTO32(Diff,Interpolate,Diff,15)
162        Product = Table[Shift+1] + (LVM_UINT32)Diff;
163
164    return Product;
165}
166