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 /* Includes */
21 /* */
22 /************************************************************************************/
23
24 #include "LVCS.h"
25 #include "LVCS_Private.h"
26 #include "LVCS_Tables.h"
27
28 /************************************************************************************/
29 /* */
30 /* FUNCTION: LVCS_GetParameters */
31 /* */
32 /* DESCRIPTION: */
33 /* Request the Concert Sound parameters. The current parameter set is returned */
34 /* via the parameter pointer. */
35 /* */
36 /* PARAMETERS: */
37 /* hInstance Instance handle */
38 /* pParams Pointer to an empty parameter structure */
39 /* */
40 /* RETURNS: */
41 /* LVCS_Success Always succeeds */
42 /* */
43 /* NOTES: */
44 /* 1. This function may be interrupted by the LVCS_Process function */
45 /* */
46 /************************************************************************************/
47
LVCS_GetParameters(LVCS_Handle_t hInstance,LVCS_Params_t * pParams)48 LVCS_ReturnStatus_en LVCS_GetParameters(LVCS_Handle_t hInstance,
49 LVCS_Params_t *pParams)
50 {
51
52 LVCS_Instance_t *pInstance =(LVCS_Instance_t *)hInstance;
53
54 *pParams = pInstance->Params;
55
56 return(LVCS_SUCCESS);
57 }
58
59
60 /************************************************************************************/
61 /* */
62 /* FUNCTION: LVCS_Control */
63 /* */
64 /* DESCRIPTION: */
65 /* Sets or changes the Concert Sound parameters. */
66 /* */
67 /* PARAMETERS: */
68 /* hInstance Instance handle */
69 /* pParams Pointer to a parameter structure */
70 /* */
71 /* RETURNS: */
72 /* LVCS_Success Succeeded */
73 /* */
74 /* NOTES: */
75 /* 1. This function must not be interrupted by the LVCS_Process function */
76 /* */
77 /************************************************************************************/
78
LVCS_Control(LVCS_Handle_t hInstance,LVCS_Params_t * pParams)79 LVCS_ReturnStatus_en LVCS_Control(LVCS_Handle_t hInstance,
80 LVCS_Params_t *pParams)
81 {
82 LVM_INT16 Offset;
83 LVCS_Instance_t *pInstance =(LVCS_Instance_t *)hInstance;
84 LVCS_ReturnStatus_en err;
85 LVCS_Modes_en OperatingModeSave = pInstance->Params.OperatingMode;
86
87 if (pParams->SampleRate != pInstance->Params.SampleRate)
88 {
89 pInstance->TimerParams.SamplingRate = LVCS_SampleRateTable[pParams->SampleRate];
90 }
91
92 /*
93 * If the reverb level has changed
94 */
95 if(pInstance->Params.ReverbLevel != pParams->ReverbLevel)
96 {
97 err=LVCS_ReverbGeneratorInit(hInstance,pParams);
98 }
99
100 /*
101 * If the sample rate or speaker has changed then perform a full re-initialisation
102 */
103 if ((pInstance->Params.SampleRate != pParams->SampleRate) ||
104 (pInstance->Params.SpeakerType != pParams->SpeakerType))
105 {
106 const LVCS_VolCorrect_t *pLVCS_VolCorrectTable;
107
108 /*
109 * Output device
110 */
111 pInstance->OutputDevice = LVCS_HEADPHONE;
112
113 /*
114 * Get the volume correction parameters
115 */
116 /* Use internal coefficient table */
117 pLVCS_VolCorrectTable = (LVCS_VolCorrect_t*)&LVCS_VolCorrectTable[0];
118 Offset = (LVM_INT16)(pParams->SpeakerType + pParams->SourceFormat*(1+LVCS_EX_HEADPHONES));
119
120 pInstance->VolCorrect = pLVCS_VolCorrectTable[Offset];
121
122 pInstance->CompressGain = pInstance->VolCorrect.CompMin;
123 #ifdef BUILD_FLOAT
124 LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[0], 0, 0);
125 #else
126 LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[0],0,0);
127 #endif
128 {
129 #ifndef BUILD_FLOAT
130 LVM_UINT32 Gain;
131 const Gain_t *pOutputGainTable = (Gain_t*)&LVCS_OutputGainTable[0];
132 Gain = (LVM_UINT32)(pOutputGainTable[Offset].Loss * LVM_MAXINT_16);
133 Gain = (LVM_UINT32)pOutputGainTable[Offset].UnprocLoss * (Gain >> 15);
134 Gain=Gain>>15;
135 /*
136 * Apply the gain correction and shift, note the result is in Q3.13 format
137 */
138 Gain = (Gain * pInstance->VolCorrect.GainMin) >>12;
139
140 LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[1],0,Gain);
141 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMix.Mixer_Instance.MixerStream[0],
142 LVCS_BYPASS_MIXER_TC,pParams->SampleRate,2);
143 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMix.Mixer_Instance.MixerStream[1],
144 LVCS_BYPASS_MIXER_TC,pParams->SampleRate,2);
145 #else
146 LVM_FLOAT Gain;
147 const Gain_t *pOutputGainTable = (Gain_t*)&LVCS_OutputGainTable[0];
148 Gain = (LVM_FLOAT)(pOutputGainTable[Offset].Loss);
149 Gain = (LVM_FLOAT)pOutputGainTable[Offset].UnprocLoss * (Gain);
150
151 /*
152 * Apply the gain correction
153 */
154 Gain = (Gain * pInstance->VolCorrect.GainMin);
155
156 LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[1], 0, Gain);
157 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMix.Mixer_Instance.MixerStream[0],
158 LVCS_BYPASS_MIXER_TC, pParams->SampleRate, 2);
159 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMix.Mixer_Instance.MixerStream[1],
160 LVCS_BYPASS_MIXER_TC, pParams->SampleRate, 2);
161 #endif
162 }
163
164
165 err=LVCS_SEnhancerInit(hInstance,
166 pParams);
167
168 err=LVCS_ReverbGeneratorInit(hInstance,
169 pParams);
170
171 err=LVCS_EqualiserInit(hInstance,
172 pParams);
173
174 err=LVCS_BypassMixInit(hInstance,
175 pParams);
176
177 }
178
179
180 /*
181 * Check if the effect level or source format has changed
182 */
183 else if ((pInstance->Params.EffectLevel != pParams->EffectLevel) ||
184 (pInstance->Params.SourceFormat != pParams->SourceFormat))
185 {
186 const LVCS_VolCorrect_t *pLVCS_VolCorrectTable;
187
188 /*
189 * Get the volume correction parameters
190 */
191 /* Use internal coefficient table */
192 pLVCS_VolCorrectTable = (LVCS_VolCorrect_t*)&LVCS_VolCorrectTable[0];
193 Offset = (LVM_INT16)(pParams->SpeakerType + pParams->SourceFormat*(1+LVCS_EX_HEADPHONES));
194
195 pInstance->VolCorrect = pLVCS_VolCorrectTable[Offset];
196
197 /* Update the effect level and alpha-mixer gains */
198 err=LVCS_BypassMixInit(hInstance,
199 pParams);
200
201 if(err != LVCS_SUCCESS)
202 {
203 return err;
204 }
205 }
206 else
207 {
208 pInstance->Params = *pParams;
209 }
210
211 /*
212 * Update the instance parameters
213 */
214 pInstance->Params = *pParams;
215
216 /* Stay on the current operating mode until the transition is done */
217 if((pParams->OperatingMode != OperatingModeSave) ||
218 (pInstance->bInOperatingModeTransition == LVM_TRUE)){
219
220 /* Set the reverb delay timeout */
221 if(pInstance->bInOperatingModeTransition != LVM_TRUE){
222 pInstance->bTimerDone = LVM_FALSE;
223 pInstance->TimerParams.TimeInMs =
224 (LVM_INT16)(((pInstance->Reverberation.DelaySize << 2)
225 /pInstance->TimerParams.SamplingRate) + 1);
226 LVM_Timer_Init ( &pInstance->TimerInstance,
227 &pInstance->TimerParams);
228 }
229
230 /* Update the effect level and alpha-mixer gains */
231 err=LVCS_BypassMixInit(hInstance,
232 pParams);
233
234 /* Change transition bypass mixer settings if needed depending on transition type */
235 if(pParams->OperatingMode != LVCS_OFF){
236 pInstance->MSTarget0=LVM_MAXINT_16;
237 pInstance->MSTarget1=0;
238 }
239 else
240 {
241 pInstance->Params.OperatingMode = OperatingModeSave;
242 pInstance->MSTarget1=LVM_MAXINT_16;
243 pInstance->MSTarget0=0;
244 }
245
246
247 /* Set transition flag */
248 pInstance->bInOperatingModeTransition = LVM_TRUE;
249 }
250
251 return(LVCS_SUCCESS);
252 }
253
254 /****************************************************************************************/
255 /* */
256 /* FUNCTION: LVCS_TimerCallBack */
257 /* */
258 /* DESCRIPTION: */
259 /* CallBack function of the Timer. */
260 /* */
261 /****************************************************************************************/
LVCS_TimerCallBack(void * hInstance,void * pCallBackParams,LVM_INT32 CallbackParam)262 void LVCS_TimerCallBack (void* hInstance, void* pCallBackParams, LVM_INT32 CallbackParam)
263 {
264 LVCS_Instance_t *pInstance = (LVCS_Instance_t *)hInstance;
265
266 /* Avoid warnings because pCallBackParams and CallbackParam are not used*/
267 if((pCallBackParams != LVM_NULL) || (CallbackParam != 0)){
268 pCallBackParams = hInstance;
269 CallbackParam = 0;
270 return;
271 }
272
273 pInstance->bTimerDone = LVM_TRUE;
274
275
276 return;
277 }
278
279