| /* |
| * Copyright (C) 2004-2010 NXP Software |
| * Copyright (C) 2010 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "LVM_Types.h" |
| #include "LVM_Macros.h" |
| #include "Mixer.h" |
| #include "LVM_Mixer_FilterCoeffs.h" |
| |
| |
| /************************************************************************/ |
| /* FUNCTION: */ |
| /* LVM_Mix_GetTimeConstant */ |
| /* */ |
| /* DESCRIPTION: */ |
| /* This function calculates the filter coefficient using the following */ |
| /* equation: */ |
| /* Alpha = exp(ln(0.1)/ (tc * Update + 1.0)) */ |
| /* */ |
| /* This is to be used with the follow first order filter, called at a */ |
| /* rate of Update times a second. tc is the required time constant in */ |
| /* units of 100us. */ |
| /* */ |
| /* Output(n) = Alpha * Output(n-1) + (1 - Alpha) * Target(n) */ |
| /* */ |
| /* The function assumes the block size is large, i.e. the update rate */ |
| /* is approximately a fixed, and correct factor of the value of Fs */ |
| /* given in the call. This is especially not true when the block size */ |
| /* is very small, see the mixer documentation for further details. */ |
| /* */ |
| /* The function does not support all possible combinations of input */ |
| /* values: */ |
| /* */ |
| /* 1. NumChannels is limited to the values 1 (Mono) and 2 (Stereo) */ |
| /* 2. The product tc * Fs is limited approximately to the range */ |
| /* 8 < (tc * Fs) < 2^35 */ |
| /* */ |
| /* PARAMETERS: */ |
| /* tc - the time constant in 100us steps, i.e. 10 = 1ms */ |
| /* Fs - the filter update rate in Hz */ |
| /* NumChannels - Number of channels 1=Mono, 2=Stereo */ |
| /* */ |
| /* RETURNS: */ |
| /* Alpha - the filter coefficient Q31 format */ |
| /* */ |
| /************************************************************************/ |
| |
| LVM_UINT32 LVM_Mixer_TimeConstant(LVM_UINT32 tc, |
| LVM_UINT16 Fs, |
| LVM_UINT16 NumChannels) |
| { |
| |
| LVM_UINT32 Product; |
| LVM_INT16 Interpolate; |
| LVM_UINT16 Shift; |
| LVM_INT32 Diff; |
| LVM_UINT32 Table[] = {ALPHA_0, /* Log spaced look-up table */ |
| ALPHA_1, |
| ALPHA_2, |
| ALPHA_3, |
| ALPHA_4, |
| ALPHA_5, |
| ALPHA_6, |
| ALPHA_7, |
| ALPHA_8, |
| ALPHA_9, |
| ALPHA_10, |
| ALPHA_11, |
| ALPHA_12, |
| ALPHA_13, |
| ALPHA_14, |
| ALPHA_15, |
| ALPHA_16, |
| ALPHA_17, |
| ALPHA_18, |
| ALPHA_19, |
| ALPHA_20, |
| ALPHA_21, |
| ALPHA_22, |
| ALPHA_23, |
| ALPHA_24, |
| ALPHA_25, |
| ALPHA_26, |
| ALPHA_27, |
| ALPHA_28, |
| ALPHA_29, |
| ALPHA_30, |
| ALPHA_31, |
| ALPHA_32, |
| ALPHA_33, |
| ALPHA_34, |
| ALPHA_35, |
| ALPHA_36, |
| ALPHA_37, |
| ALPHA_38, |
| ALPHA_39, |
| ALPHA_40, |
| ALPHA_41, |
| ALPHA_42, |
| ALPHA_43, |
| ALPHA_44, |
| ALPHA_45, |
| ALPHA_46, |
| ALPHA_47, |
| ALPHA_48, |
| ALPHA_49, |
| ALPHA_50}; |
| |
| |
| /* Calculate the product of the time constant and the sample rate */ |
| Product = ((tc >> 16) * (LVM_UINT32)Fs) << 13; /* Stereo value */ |
| Product = Product + (((tc & 0x0000FFFF) * (LVM_UINT32)Fs) >> 3); |
| |
| if (NumChannels == 1) |
| { |
| Product = Product >> 1; /* Mono value */ |
| } |
| |
| /* Normalize to get the table index and interpolation factor */ |
| for (Shift=0; Shift<((Alpha_TableSize-1)/2); Shift++) |
| { |
| if ((Product & 0x80000000)!=0) |
| { |
| break; |
| } |
| |
| Product = Product << 1; |
| } |
| Shift = (LVM_UINT16)((Shift << 1)); |
| |
| if ((Product & 0x40000000)==0) |
| { |
| Shift++; |
| } |
| |
| Interpolate = (LVM_INT16)((Product >> 15) & 0x00007FFF); |
| |
| Diff = (LVM_INT32)(Table[Shift] - Table[Shift+1]); |
| MUL32x16INTO32(Diff,Interpolate,Diff,15) |
| Product = Table[Shift+1] + (LVM_UINT32)Diff; |
| |
| return Product; |
| } |