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, LVCS_Params_t* pParams) {
49 LVCS_Instance_t* pInstance = (LVCS_Instance_t*)hInstance;
50
51 *pParams = pInstance->Params;
52
53 return (LVCS_SUCCESS);
54 }
55
56 /************************************************************************************/
57 /* */
58 /* FUNCTION: LVCS_Control */
59 /* */
60 /* DESCRIPTION: */
61 /* Sets or changes the Concert Sound parameters. */
62 /* */
63 /* PARAMETERS: */
64 /* hInstance Instance handle */
65 /* pParams Pointer to a parameter structure */
66 /* */
67 /* RETURNS: */
68 /* LVCS_Success Succeeded */
69 /* */
70 /* NOTES: */
71 /* 1. This function must not be interrupted by the LVCS_Process function */
72 /* */
73 /************************************************************************************/
74
LVCS_Control(LVCS_Handle_t hInstance,LVCS_Params_t * pParams)75 LVCS_ReturnStatus_en LVCS_Control(LVCS_Handle_t hInstance, LVCS_Params_t* pParams) {
76 LVM_INT16 Offset;
77 LVCS_Instance_t* pInstance = (LVCS_Instance_t*)hInstance;
78 LVCS_ReturnStatus_en err;
79 LVCS_Modes_en OperatingModeSave = pInstance->Params.OperatingMode;
80
81 if (pParams->SampleRate != pInstance->Params.SampleRate) {
82 pInstance->TimerParams.SamplingRate = LVCS_SampleRateTable[pParams->SampleRate];
83 }
84
85 /*
86 * If the reverb level has changed
87 */
88 if (pInstance->Params.ReverbLevel != pParams->ReverbLevel) {
89 err = LVCS_ReverbGeneratorInit(hInstance, pParams);
90 }
91
92 /*
93 * If the sample rate or speaker has changed then perform a full re-initialisation
94 */
95 if ((pInstance->Params.SampleRate != pParams->SampleRate) ||
96 (pInstance->Params.SpeakerType != pParams->SpeakerType)) {
97 const LVCS_VolCorrect_t* pLVCS_VolCorrectTable;
98
99 /*
100 * Output device
101 */
102 pInstance->OutputDevice = LVCS_HEADPHONE;
103
104 /*
105 * Get the volume correction parameters
106 */
107 /* Use internal coefficient table */
108 pLVCS_VolCorrectTable = (LVCS_VolCorrect_t*)&LVCS_VolCorrectTable[0];
109 Offset = (LVM_INT16)(pParams->SpeakerType +
110 pParams->SourceFormat * (1 + LVCS_EX_HEADPHONES));
111
112 pInstance->VolCorrect = pLVCS_VolCorrectTable[Offset];
113
114 pInstance->CompressGain = pInstance->VolCorrect.CompMin;
115 LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[0], 0, 0);
116 {
117 LVM_FLOAT Gain;
118 const Gain_t* pOutputGainTable = (Gain_t*)&LVCS_OutputGainTable[0];
119 Gain = (LVM_FLOAT)(pOutputGainTable[Offset].Loss);
120 Gain = (LVM_FLOAT)pOutputGainTable[Offset].UnprocLoss * (Gain);
121
122 /*
123 * Apply the gain correction
124 */
125 Gain = (Gain * pInstance->VolCorrect.GainMin);
126
127 LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[1], 0, Gain);
128 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMix.Mixer_Instance.MixerStream[0],
129 LVCS_BYPASS_MIXER_TC, pParams->SampleRate, 2);
130 LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMix.Mixer_Instance.MixerStream[1],
131 LVCS_BYPASS_MIXER_TC, pParams->SampleRate, 2);
132 }
133
134 err = LVCS_SEnhancerInit(hInstance, pParams);
135
136 err = LVCS_ReverbGeneratorInit(hInstance, pParams);
137
138 err = LVCS_EqualiserInit(hInstance, pParams);
139
140 err = LVCS_BypassMixInit(hInstance, pParams);
141
142 }
143
144 /*
145 * Check if the effect level or source format has changed
146 */
147 else if ((pInstance->Params.EffectLevel != pParams->EffectLevel) ||
148 (pInstance->Params.SourceFormat != pParams->SourceFormat)) {
149 const LVCS_VolCorrect_t* pLVCS_VolCorrectTable;
150
151 /*
152 * Get the volume correction parameters
153 */
154 /* Use internal coefficient table */
155 pLVCS_VolCorrectTable = (LVCS_VolCorrect_t*)&LVCS_VolCorrectTable[0];
156 Offset = (LVM_INT16)(pParams->SpeakerType +
157 pParams->SourceFormat * (1 + LVCS_EX_HEADPHONES));
158
159 pInstance->VolCorrect = pLVCS_VolCorrectTable[Offset];
160
161 /* Update the effect level and alpha-mixer gains */
162 err = LVCS_BypassMixInit(hInstance, pParams);
163
164 if (err != LVCS_SUCCESS) {
165 return err;
166 }
167 } else {
168 pInstance->Params = *pParams;
169 }
170
171 /*
172 * Update the instance parameters
173 */
174 pInstance->Params = *pParams;
175
176 /* Stay on the current operating mode until the transition is done */
177 if ((pParams->OperatingMode != OperatingModeSave) ||
178 (pInstance->bInOperatingModeTransition == LVM_TRUE)) {
179 /* Set the reverb delay timeout */
180 if (pInstance->bInOperatingModeTransition != LVM_TRUE) {
181 pInstance->bTimerDone = LVM_FALSE;
182 pInstance->TimerParams.TimeInMs =
183 (LVM_INT16)(((pInstance->Params.NrChannels == FCC_1
184 ? pInstance->Reverberation.DelaySize << 3
185 : pInstance->Reverberation.DelaySize << 2) /
186 pInstance->TimerParams.SamplingRate) +
187 1);
188 LVM_Timer_Init(&pInstance->TimerInstance, &pInstance->TimerParams);
189 }
190
191 /* Update the effect level and alpha-mixer gains */
192 err = LVCS_BypassMixInit(hInstance, pParams);
193
194 /* Change transition bypass mixer settings if needed depending on transition type */
195 if (pParams->OperatingMode != LVCS_OFF) {
196 pInstance->MSTarget0 = LVM_MAXINT_16;
197 pInstance->MSTarget1 = 0;
198 } else {
199 pInstance->Params.OperatingMode = OperatingModeSave;
200 pInstance->MSTarget1 = LVM_MAXINT_16;
201 pInstance->MSTarget0 = 0;
202 }
203
204 /* Set transition flag */
205 pInstance->bInOperatingModeTransition = LVM_TRUE;
206 }
207
208 return (LVCS_SUCCESS);
209 }
210
211 /****************************************************************************************/
212 /* */
213 /* FUNCTION: LVCS_TimerCallBack */
214 /* */
215 /* DESCRIPTION: */
216 /* CallBack function of the Timer. */
217 /* */
218 /****************************************************************************************/
LVCS_TimerCallBack(void * hInstance,void * pCallBackParams,LVM_INT32 CallbackParam)219 void LVCS_TimerCallBack(void* hInstance, void* pCallBackParams, LVM_INT32 CallbackParam) {
220 LVCS_Instance_t* pInstance = (LVCS_Instance_t*)hInstance;
221
222 /* Avoid warnings because pCallBackParams and CallbackParam are not used*/
223 if ((pCallBackParams != LVM_NULL) || (CallbackParam != 0)) {
224 pCallBackParams = hInstance;
225 CallbackParam = 0;
226 return;
227 }
228
229 pInstance->bTimerDone = LVM_TRUE;
230
231 return;
232 }
233