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 INCLUDE FILES
20 ***********************************************************************************/
21
22 #include "LVC_Mixer_Private.h"
23 #include "VectorArithmetic.h"
24 #include "ScalarArithmetic.h"
25
26 /**********************************************************************************
27 DEFINITIONS
28 ***********************************************************************************/
29
30 #define TRUE 1
31 #define FALSE 0
32
33 /**********************************************************************************
34 FUNCTION LVC_MixSoft_1St_2i_D16C31_SAT
35 ***********************************************************************************/
36 #ifdef BUILD_FLOAT
LVC_MixSoft_1St_2i_D16C31_SAT(LVMixer3_2St_FLOAT_st * ptrInstance,const LVM_FLOAT * src,LVM_FLOAT * dst,LVM_INT16 n)37 void LVC_MixSoft_1St_2i_D16C31_SAT( LVMixer3_2St_FLOAT_st *ptrInstance,
38 const LVM_FLOAT *src,
39 LVM_FLOAT *dst,
40 LVM_INT16 n)
41 {
42 char HardMixing = TRUE;
43 LVM_FLOAT TargetGain;
44 Mix_Private_FLOAT_st *pInstance1 = \
45 (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[0].PrivateParams);
46 Mix_Private_FLOAT_st *pInstance2 = \
47 (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[1].PrivateParams);
48
49 if(n <= 0) return;
50
51 /******************************************************************************
52 SOFT MIXING
53 *******************************************************************************/
54 if ((pInstance1->Current != pInstance1->Target) || (pInstance2->Current != pInstance2->Target))
55 {
56 if(pInstance1->Delta == 1.0f)
57 {
58 pInstance1->Current = pInstance1->Target;
59 TargetGain = pInstance1->Target;
60 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
61 }
62 else if (Abs_Float(pInstance1->Current - pInstance1->Target) < pInstance1->Delta)
63 {
64 pInstance1->Current = pInstance1->Target; /* Difference is not significant anymore. \
65 Make them equal. */
66 TargetGain = pInstance1->Target;
67 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
68 }
69 else
70 {
71 /* Soft mixing has to be applied */
72 HardMixing = FALSE;
73 }
74
75 if(HardMixing == TRUE)
76 {
77 if(pInstance2->Delta == 1.0f)
78 {
79 pInstance2->Current = pInstance2->Target;
80 TargetGain = pInstance2->Target;
81 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[1]), TargetGain);
82 }
83 else if (Abs_Float(pInstance2->Current - pInstance2->Target) < pInstance2->Delta)
84 {
85 pInstance2->Current = pInstance2->Target; /* Difference is not significant anymore. \
86 Make them equal. */
87 TargetGain = pInstance2->Target;
88 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[1]), TargetGain);
89 }
90 else
91 {
92 /* Soft mixing has to be applied */
93 HardMixing = FALSE;
94 }
95 }
96
97 if(HardMixing == FALSE)
98 {
99 LVC_Core_MixSoft_1St_2i_D16C31_WRA( &(ptrInstance->MixerStream[0]),
100 &(ptrInstance->MixerStream[1]),
101 src, dst, n);
102 }
103 }
104
105 /******************************************************************************
106 HARD MIXING
107 *******************************************************************************/
108
109 if (HardMixing)
110 {
111 if ((pInstance1->Target == 1.0f) && (pInstance2->Target == 1.0f))
112 {
113 if(src != dst)
114 {
115 Copy_Float(src, dst, n);
116 }
117 }
118 else
119 {
120 LVC_Core_MixHard_1St_2i_D16C31_SAT(&(ptrInstance->MixerStream[0]),
121 &(ptrInstance->MixerStream[1]),
122 src, dst, n);
123 }
124 }
125
126 /******************************************************************************
127 CALL BACK
128 *******************************************************************************/
129
130 if (ptrInstance->MixerStream[0].CallbackSet)
131 {
132 if (Abs_Float(pInstance1->Current - pInstance1->Target) < pInstance1->Delta)
133 {
134 pInstance1->Current = pInstance1->Target; /* Difference is not significant anymore. \
135 Make them equal. */
136 TargetGain = pInstance1->Target;
137 LVC_Mixer_SetTarget(&ptrInstance->MixerStream[0], TargetGain);
138 ptrInstance->MixerStream[0].CallbackSet = FALSE;
139 if (ptrInstance->MixerStream[0].pCallBack != 0)
140 {
141 (*ptrInstance->MixerStream[0].pCallBack) ( \
142 ptrInstance->MixerStream[0].pCallbackHandle,
143 ptrInstance->MixerStream[0].pGeneralPurpose,
144 ptrInstance->MixerStream[0].CallbackParam );
145 }
146 }
147 }
148 if (ptrInstance->MixerStream[1].CallbackSet)
149 {
150 if (Abs_Float(pInstance2->Current - pInstance2->Target) < pInstance2->Delta)
151 {
152 pInstance2->Current = pInstance2->Target; /* Difference is not significant anymore.
153 Make them equal. */
154 TargetGain = pInstance2->Target;
155 LVC_Mixer_SetTarget(&ptrInstance->MixerStream[1], TargetGain);
156 ptrInstance->MixerStream[1].CallbackSet = FALSE;
157 if (ptrInstance->MixerStream[1].pCallBack != 0)
158 {
159 (*ptrInstance->MixerStream[1].pCallBack) (
160 ptrInstance->MixerStream[1].pCallbackHandle,
161 ptrInstance->MixerStream[1].pGeneralPurpose,
162 ptrInstance->MixerStream[1].CallbackParam );
163 }
164 }
165 }
166 }
167 #else
LVC_MixSoft_1St_2i_D16C31_SAT(LVMixer3_2St_st * ptrInstance,const LVM_INT16 * src,LVM_INT16 * dst,LVM_INT16 n)168 void LVC_MixSoft_1St_2i_D16C31_SAT( LVMixer3_2St_st *ptrInstance,
169 const LVM_INT16 *src,
170 LVM_INT16 *dst,
171 LVM_INT16 n)
172 {
173 char HardMixing = TRUE;
174 LVM_INT32 TargetGain;
175 Mix_Private_st *pInstance1=(Mix_Private_st *)(ptrInstance->MixerStream[0].PrivateParams);
176 Mix_Private_st *pInstance2=(Mix_Private_st *)(ptrInstance->MixerStream[1].PrivateParams);
177
178 if(n<=0) return;
179
180 /******************************************************************************
181 SOFT MIXING
182 *******************************************************************************/
183 if ((pInstance1->Current != pInstance1->Target)||(pInstance2->Current != pInstance2->Target))
184 {
185 if(pInstance1->Delta == 0x7FFFFFFF)
186 {
187 pInstance1->Current = pInstance1->Target;
188 TargetGain=pInstance1->Target>>16; // TargetGain in Q16.15 format, no integer part
189 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]),TargetGain);
190 }
191 else if (Abs_32(pInstance1->Current-pInstance1->Target) < pInstance1->Delta)
192 {
193 pInstance1->Current = pInstance1->Target; /* Difference is not significant anymore. Make them equal. */
194 TargetGain=pInstance1->Target>>16; // TargetGain in Q16.15 format, no integer part
195 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]),TargetGain);
196 }
197 else
198 {
199 /* Soft mixing has to be applied */
200 HardMixing = FALSE;
201 }
202
203 if(HardMixing == TRUE)
204 {
205 if(pInstance2->Delta == 0x7FFFFFFF)
206 {
207 pInstance2->Current = pInstance2->Target;
208 TargetGain=pInstance2->Target>>16; // TargetGain in Q16.15 format, no integer part
209 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[1]),TargetGain);
210 }
211 else if (Abs_32(pInstance2->Current-pInstance2->Target) < pInstance2->Delta)
212 {
213 pInstance2->Current = pInstance2->Target; /* Difference is not significant anymore. Make them equal. */
214 TargetGain=pInstance2->Target>>16; // TargetGain in Q16.15 format, no integer part
215 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[1]),TargetGain);
216 }
217 else
218 {
219 /* Soft mixing has to be applied */
220 HardMixing = FALSE;
221 }
222 }
223
224 if(HardMixing == FALSE)
225 {
226 LVC_Core_MixSoft_1St_2i_D16C31_WRA( &(ptrInstance->MixerStream[0]),&(ptrInstance->MixerStream[1]), src, dst, n);
227 }
228 }
229
230 /******************************************************************************
231 HARD MIXING
232 *******************************************************************************/
233
234 if (HardMixing)
235 {
236 if (((pInstance1->Target>>16) == 0x7FFF)&&((pInstance2->Target>>16) == 0x7FFF))
237 {
238 if(src!=dst)
239 {
240 Copy_16(src, dst, n);
241 }
242 }
243 else
244 {
245 LVC_Core_MixHard_1St_2i_D16C31_SAT(&(ptrInstance->MixerStream[0]),&(ptrInstance->MixerStream[1]), src, dst, n);
246 }
247 }
248
249 /******************************************************************************
250 CALL BACK
251 *******************************************************************************/
252
253 if (ptrInstance->MixerStream[0].CallbackSet)
254 {
255 if (Abs_32(pInstance1->Current-pInstance1->Target) < pInstance1->Delta)
256 {
257 pInstance1->Current = pInstance1->Target; /* Difference is not significant anymore. Make them equal. */
258 TargetGain=pInstance1->Target>>(16-pInstance1->Shift); // TargetGain in Q16.15 format
259 LVC_Mixer_SetTarget(&ptrInstance->MixerStream[0],TargetGain);
260 ptrInstance->MixerStream[0].CallbackSet = FALSE;
261 if (ptrInstance->MixerStream[0].pCallBack != 0)
262 {
263 (*ptrInstance->MixerStream[0].pCallBack) ( ptrInstance->MixerStream[0].pCallbackHandle, ptrInstance->MixerStream[0].pGeneralPurpose,ptrInstance->MixerStream[0].CallbackParam );
264 }
265 }
266 }
267 if (ptrInstance->MixerStream[1].CallbackSet)
268 {
269 if (Abs_32(pInstance2->Current-pInstance2->Target) < pInstance2->Delta)
270 {
271 pInstance2->Current = pInstance2->Target; /* Difference is not significant anymore. Make them equal. */
272 TargetGain=pInstance2->Target>>(16-pInstance2->Shift); // TargetGain in Q16.15 format
273 LVC_Mixer_SetTarget(&ptrInstance->MixerStream[1],TargetGain);
274 ptrInstance->MixerStream[1].CallbackSet = FALSE;
275 if (ptrInstance->MixerStream[1].pCallBack != 0)
276 {
277 (*ptrInstance->MixerStream[1].pCallBack) ( ptrInstance->MixerStream[1].pCallbackHandle, ptrInstance->MixerStream[1].pGeneralPurpose,ptrInstance->MixerStream[1].CallbackParam );
278 }
279 }
280 }
281 }
282 #endif
283 /**********************************************************************************/
284