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