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 
124         LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[0],0,0);
125 
126 
127         {
128             LVM_UINT32          Gain;
129             const Gain_t        *pOutputGainTable = (Gain_t*)&LVCS_OutputGainTable[0];
130             Gain = (LVM_UINT32)(pOutputGainTable[Offset].Loss * LVM_MAXINT_16);
131             Gain = (LVM_UINT32)pOutputGainTable[Offset].UnprocLoss * (Gain >> 15);
132             Gain=Gain>>15;
133             /*
134              * Apply the gain correction and shift, note the result is in Q3.13 format
135              */
136             Gain = (Gain * pInstance->VolCorrect.GainMin) >>12;
137 
138             LVC_Mixer_Init(&pInstance->BypassMix.Mixer_Instance.MixerStream[1],0,Gain);
139             LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMix.Mixer_Instance.MixerStream[0],
140                     LVCS_BYPASS_MIXER_TC,pParams->SampleRate,2);
141             LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMix.Mixer_Instance.MixerStream[1],
142                     LVCS_BYPASS_MIXER_TC,pParams->SampleRate,2);
143 
144         }
145 
146 
147         err=LVCS_SEnhancerInit(hInstance,
148                            pParams);
149 
150         err=LVCS_ReverbGeneratorInit(hInstance,
151                                  pParams);
152 
153         err=LVCS_EqualiserInit(hInstance,
154                            pParams);
155 
156         err=LVCS_BypassMixInit(hInstance,
157                            pParams);
158 
159     }
160 
161 
162     /*
163      * Check if the effect level or source format has changed
164      */
165     else if ((pInstance->Params.EffectLevel != pParams->EffectLevel) ||
166             (pInstance->Params.SourceFormat != pParams->SourceFormat))
167     {
168         const LVCS_VolCorrect_t *pLVCS_VolCorrectTable;
169 
170         /*
171          * Get the volume correction parameters
172          */
173         /* Use internal coefficient table */
174         pLVCS_VolCorrectTable = (LVCS_VolCorrect_t*)&LVCS_VolCorrectTable[0];
175         Offset = (LVM_INT16)(pParams->SpeakerType + pParams->SourceFormat*(1+LVCS_EX_HEADPHONES));
176 
177         pInstance->VolCorrect = pLVCS_VolCorrectTable[Offset];
178 
179         /* Update the effect level and alpha-mixer gains */
180         err=LVCS_BypassMixInit(hInstance,
181                            pParams);
182 
183         if(err != LVCS_SUCCESS)
184         {
185             return err;
186         }
187     }
188     else
189     {
190         pInstance->Params = *pParams;
191     }
192 
193     /*
194      * Update the instance parameters
195      */
196     pInstance->Params = *pParams;
197 
198     /* Stay on the current operating mode until the transition is done */
199     if((pParams->OperatingMode != OperatingModeSave) ||
200        (pInstance->bInOperatingModeTransition == LVM_TRUE)){
201 
202         /* Set the reverb delay timeout */
203         if(pInstance->bInOperatingModeTransition != LVM_TRUE){
204             pInstance->bTimerDone = LVM_FALSE;
205             pInstance->TimerParams.TimeInMs =
206             (LVM_INT16)(((pInstance->Reverberation.DelaySize << 2)
207             /pInstance->TimerParams.SamplingRate) + 1);
208             LVM_Timer_Init ( &pInstance->TimerInstance,
209                              &pInstance->TimerParams);
210         }
211 
212         /* Update the effect level and alpha-mixer gains */
213         err=LVCS_BypassMixInit(hInstance,
214                            pParams);
215 
216         /* Change transition bypass mixer settings if needed depending on transition type */
217         if(pParams->OperatingMode != LVCS_OFF){
218             pInstance->MSTarget0=LVM_MAXINT_16;
219             pInstance->MSTarget1=0;
220         }
221         else
222         {
223             pInstance->Params.OperatingMode = OperatingModeSave;
224             pInstance->MSTarget1=LVM_MAXINT_16;
225             pInstance->MSTarget0=0;
226         }
227 
228 
229         /* Set transition flag */
230         pInstance->bInOperatingModeTransition = LVM_TRUE;
231     }
232 
233     return(LVCS_SUCCESS);
234 }
235 
236 /****************************************************************************************/
237 /*                                                                                      */
238 /* FUNCTION:                LVCS_TimerCallBack                                          */
239 /*                                                                                      */
240 /* DESCRIPTION:                                                                         */
241 /*  CallBack function of the Timer.                                                     */
242 /*                                                                                      */
243 /****************************************************************************************/
LVCS_TimerCallBack(void * hInstance,void * pCallBackParams,LVM_INT32 CallbackParam)244 void LVCS_TimerCallBack (void* hInstance, void* pCallBackParams, LVM_INT32 CallbackParam)
245 {
246     LVCS_Instance_t     *pInstance  = (LVCS_Instance_t  *)hInstance;
247 
248     /* Avoid warnings because pCallBackParams and CallbackParam are not used*/
249     if((pCallBackParams != LVM_NULL) || (CallbackParam != 0)){
250         pCallBackParams = hInstance;
251         CallbackParam = 0;
252         return;
253     }
254 
255     pInstance->bTimerDone = LVM_TRUE;
256 
257 
258     return;
259 }
260 
261