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