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