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 MIXINSOFT_D16C31_SAT
35 ***********************************************************************************/
36 #ifdef BUILD_FLOAT
LVC_MixInSoft_D16C31_SAT(LVMixer3_1St_FLOAT_st * ptrInstance,const LVM_FLOAT * src,LVM_FLOAT * dst,LVM_INT16 n)37 void LVC_MixInSoft_D16C31_SAT(LVMixer3_1St_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 *pInstance = \
45 (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[0].PrivateParams);
46
47 if(n <= 0) return;
48
49 /******************************************************************************
50 SOFT MIXING
51 *******************************************************************************/
52 if (pInstance->Current != pInstance->Target)
53 {
54 if(pInstance->Delta == 1.0f){
55 pInstance->Current = pInstance->Target;
56 TargetGain = pInstance->Target;
57 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
58 }else if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta){
59 pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
60 Make them equal. */
61 TargetGain = pInstance->Target;
62 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
63 }else{
64 /* Soft mixing has to be applied */
65 HardMixing = FALSE;
66 LVC_Core_MixInSoft_D16C31_SAT(&(ptrInstance->MixerStream[0]), src, dst, n);
67 }
68 }
69
70 /******************************************************************************
71 HARD MIXING
72 *******************************************************************************/
73
74 if (HardMixing){
75 if (pInstance->Target != 0){ /* Nothing to do in case Target = 0 */
76 if ((pInstance->Target) == 1.0f){
77 Add2_Sat_Float(src, dst, n);
78 }
79 else{
80 Mac3s_Sat_Float(src, (pInstance->Target), dst, n);
81 /* In case the LVCore function would have changed the Current value */
82 pInstance->Current = pInstance->Target;
83 }
84 }
85 }
86
87
88 /******************************************************************************
89 CALL BACK
90 *******************************************************************************/
91
92 if (ptrInstance->MixerStream[0].CallbackSet){
93 if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta){
94 pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
95 Make them equal. */
96 TargetGain = pInstance->Target;
97 LVC_Mixer_SetTarget(ptrInstance->MixerStream, TargetGain);
98 ptrInstance->MixerStream[0].CallbackSet = FALSE;
99 if (ptrInstance->MixerStream[0].pCallBack != 0){
100 (*ptrInstance->MixerStream[0].pCallBack) ( \
101 ptrInstance->MixerStream[0].pCallbackHandle,
102 ptrInstance->MixerStream[0].pGeneralPurpose,
103 ptrInstance->MixerStream[0].CallbackParam );
104 }
105 }
106 }
107
108 }
109
110
111
112 #ifdef SUPPORT_MC
113 /*
114 * FUNCTION: LVC_MixInSoft_Mc_D16C31_SAT
115 *
116 * DESCRIPTION:
117 * Mixer function with support for processing multichannel input
118 *
119 * PARAMETERS:
120 * ptrInstance Instance pointer
121 * src Source
122 * dst Destination
123 * NrFrames Number of frames
124 * NrChannels Number of channels
125 *
126 * RETURNS:
127 * void
128 *
129 */
LVC_MixInSoft_Mc_D16C31_SAT(LVMixer3_1St_FLOAT_st * ptrInstance,const LVM_FLOAT * src,LVM_FLOAT * dst,LVM_INT16 NrFrames,LVM_INT16 NrChannels)130 void LVC_MixInSoft_Mc_D16C31_SAT(LVMixer3_1St_FLOAT_st *ptrInstance,
131 const LVM_FLOAT *src,
132 LVM_FLOAT *dst,
133 LVM_INT16 NrFrames,
134 LVM_INT16 NrChannels)
135 {
136 char HardMixing = TRUE;
137 LVM_FLOAT TargetGain;
138 Mix_Private_FLOAT_st *pInstance = \
139 (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[0].PrivateParams);
140
141 if (NrFrames <= 0) return;
142
143 /******************************************************************************
144 SOFT MIXING
145 *******************************************************************************/
146 if (pInstance->Current != pInstance->Target)
147 {
148 if (pInstance->Delta == 1.0f) {
149 pInstance->Current = pInstance->Target;
150 TargetGain = pInstance->Target;
151 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
152 }else if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta) {
153 pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
154 Make them equal. */
155 TargetGain = pInstance->Target;
156 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
157 }else{
158 /* Soft mixing has to be applied */
159 HardMixing = FALSE;
160 LVC_Core_MixInSoft_Mc_D16C31_SAT(&(ptrInstance->MixerStream[0]),
161 src,
162 dst,
163 NrFrames,
164 NrChannels);
165 }
166 }
167
168 /******************************************************************************
169 HARD MIXING
170 *******************************************************************************/
171
172 if (HardMixing) {
173 if (pInstance->Target != 0) { /* Nothing to do in case Target = 0 */
174 if ((pInstance->Target) == 1.0f) {
175 Add2_Sat_Float(src, dst, NrFrames*NrChannels);
176 }
177 else{
178 Mac3s_Sat_Float(src,
179 (pInstance->Target),
180 dst,
181 NrFrames * NrChannels);
182 /* In case the LVCore function would have changed the Current value */
183 pInstance->Current = pInstance->Target;
184 }
185 }
186 }
187
188
189 /******************************************************************************
190 CALL BACK
191 *******************************************************************************/
192
193 if (ptrInstance->MixerStream[0].CallbackSet) {
194 if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta) {
195 pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
196 Make them equal. */
197 TargetGain = pInstance->Target;
198 LVC_Mixer_SetTarget(ptrInstance->MixerStream, TargetGain);
199 ptrInstance->MixerStream[0].CallbackSet = FALSE;
200 if (ptrInstance->MixerStream[0].pCallBack != 0) {
201 (*ptrInstance->MixerStream[0].pCallBack) (\
202 ptrInstance->MixerStream[0].pCallbackHandle,
203 ptrInstance->MixerStream[0].pGeneralPurpose,
204 ptrInstance->MixerStream[0].CallbackParam);
205 }
206 }
207 }
208
209 }
210 #endif
211
212
213 #else
LVC_MixInSoft_D16C31_SAT(LVMixer3_1St_st * ptrInstance,LVM_INT16 * src,LVM_INT16 * dst,LVM_INT16 n)214 void LVC_MixInSoft_D16C31_SAT( LVMixer3_1St_st *ptrInstance,
215 LVM_INT16 *src,
216 LVM_INT16 *dst,
217 LVM_INT16 n)
218 {
219 char HardMixing = TRUE;
220 LVM_INT32 TargetGain;
221 Mix_Private_st *pInstance=(Mix_Private_st *)(ptrInstance->MixerStream[0].PrivateParams);
222
223 if(n<=0) return;
224
225 /******************************************************************************
226 SOFT MIXING
227 *******************************************************************************/
228 if (pInstance->Current != pInstance->Target)
229 {
230 if(pInstance->Delta == 0x7FFFFFFF){
231 pInstance->Current = pInstance->Target;
232 TargetGain=pInstance->Target>>(16-pInstance->Shift); // TargetGain in Q16.15 format
233 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]),TargetGain);
234 }else if (Abs_32(pInstance->Current-pInstance->Target) < pInstance->Delta){
235 pInstance->Current = pInstance->Target; /* Difference is not significant anymore. Make them equal. */
236 TargetGain=pInstance->Target>>(16-pInstance->Shift); // TargetGain in Q16.15 format
237 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]),TargetGain);
238 }else{
239 /* Soft mixing has to be applied */
240 HardMixing = FALSE;
241 if(pInstance->Shift!=0){
242 Shift_Sat_v16xv16 ((LVM_INT16)pInstance->Shift,src,src,n);
243 LVC_Core_MixInSoft_D16C31_SAT( &(ptrInstance->MixerStream[0]), src, dst, n);
244 }
245 else
246 LVC_Core_MixInSoft_D16C31_SAT( &(ptrInstance->MixerStream[0]), src, dst, n);
247 }
248 }
249
250 /******************************************************************************
251 HARD MIXING
252 *******************************************************************************/
253
254 if (HardMixing){
255 if (pInstance->Target != 0){ /* Nothing to do in case Target = 0 */
256 if ((pInstance->Target>>16) == 0x7FFF){
257 if(pInstance->Shift!=0)
258 Shift_Sat_v16xv16 ((LVM_INT16)pInstance->Shift,src,src,n);
259 Add2_Sat_16x16( src, dst, n );
260 }
261 else{
262 if(pInstance->Shift!=0)
263 Shift_Sat_v16xv16 ((LVM_INT16)pInstance->Shift,src,src,n);
264 Mac3s_Sat_16x16(src,(LVM_INT16)(pInstance->Target>>16),dst,n);
265 pInstance->Current = pInstance->Target; /* In case the LVCore function would have changed the Current value */
266 }
267 }
268 }
269
270
271 /******************************************************************************
272 CALL BACK
273 *******************************************************************************/
274
275 if (ptrInstance->MixerStream[0].CallbackSet){
276 if (Abs_32(pInstance->Current-pInstance->Target) < pInstance->Delta){
277 pInstance->Current = pInstance->Target; /* Difference is not significant anymore. Make them equal. */
278 TargetGain=pInstance->Target>>(16-pInstance->Shift); // TargetGain in Q16.15 format
279 LVC_Mixer_SetTarget(ptrInstance->MixerStream,TargetGain);
280 ptrInstance->MixerStream[0].CallbackSet = FALSE;
281 if (ptrInstance->MixerStream[0].pCallBack != 0){
282 (*ptrInstance->MixerStream[0].pCallBack) ( ptrInstance->MixerStream[0].pCallbackHandle, ptrInstance->MixerStream[0].pGeneralPurpose,ptrInstance->MixerStream[0].CallbackParam );
283 }
284 }
285 }
286
287 }
288 #endif
289 /**********************************************************************************/
290