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,LVM_FLOAT * src,LVM_FLOAT * dst,LVM_INT16 n)37 void LVC_MixInSoft_D16C31_SAT( LVMixer3_1St_FLOAT_st *ptrInstance,
38 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 #else
LVC_MixInSoft_D16C31_SAT(LVMixer3_1St_st * ptrInstance,LVM_INT16 * src,LVM_INT16 * dst,LVM_INT16 n)110 void LVC_MixInSoft_D16C31_SAT( LVMixer3_1St_st *ptrInstance,
111 LVM_INT16 *src,
112 LVM_INT16 *dst,
113 LVM_INT16 n)
114 {
115 char HardMixing = TRUE;
116 LVM_INT32 TargetGain;
117 Mix_Private_st *pInstance=(Mix_Private_st *)(ptrInstance->MixerStream[0].PrivateParams);
118
119 if(n<=0) return;
120
121 /******************************************************************************
122 SOFT MIXING
123 *******************************************************************************/
124 if (pInstance->Current != pInstance->Target)
125 {
126 if(pInstance->Delta == 0x7FFFFFFF){
127 pInstance->Current = pInstance->Target;
128 TargetGain=pInstance->Target>>(16-pInstance->Shift); // TargetGain in Q16.15 format
129 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]),TargetGain);
130 }else if (Abs_32(pInstance->Current-pInstance->Target) < pInstance->Delta){
131 pInstance->Current = pInstance->Target; /* Difference is not significant anymore. Make them equal. */
132 TargetGain=pInstance->Target>>(16-pInstance->Shift); // TargetGain in Q16.15 format
133 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]),TargetGain);
134 }else{
135 /* Soft mixing has to be applied */
136 HardMixing = FALSE;
137 if(pInstance->Shift!=0){
138 Shift_Sat_v16xv16 ((LVM_INT16)pInstance->Shift,src,src,n);
139 LVC_Core_MixInSoft_D16C31_SAT( &(ptrInstance->MixerStream[0]), src, dst, n);
140 }
141 else
142 LVC_Core_MixInSoft_D16C31_SAT( &(ptrInstance->MixerStream[0]), src, dst, n);
143 }
144 }
145
146 /******************************************************************************
147 HARD MIXING
148 *******************************************************************************/
149
150 if (HardMixing){
151 if (pInstance->Target != 0){ /* Nothing to do in case Target = 0 */
152 if ((pInstance->Target>>16) == 0x7FFF){
153 if(pInstance->Shift!=0)
154 Shift_Sat_v16xv16 ((LVM_INT16)pInstance->Shift,src,src,n);
155 Add2_Sat_16x16( src, dst, n );
156 }
157 else{
158 if(pInstance->Shift!=0)
159 Shift_Sat_v16xv16 ((LVM_INT16)pInstance->Shift,src,src,n);
160 Mac3s_Sat_16x16(src,(LVM_INT16)(pInstance->Target>>16),dst,n);
161 pInstance->Current = pInstance->Target; /* In case the LVCore function would have changed the Current value */
162 }
163 }
164 }
165
166
167 /******************************************************************************
168 CALL BACK
169 *******************************************************************************/
170
171 if (ptrInstance->MixerStream[0].CallbackSet){
172 if (Abs_32(pInstance->Current-pInstance->Target) < pInstance->Delta){
173 pInstance->Current = pInstance->Target; /* Difference is not significant anymore. Make them equal. */
174 TargetGain=pInstance->Target>>(16-pInstance->Shift); // TargetGain in Q16.15 format
175 LVC_Mixer_SetTarget(ptrInstance->MixerStream,TargetGain);
176 ptrInstance->MixerStream[0].CallbackSet = FALSE;
177 if (ptrInstance->MixerStream[0].pCallBack != 0){
178 (*ptrInstance->MixerStream[0].pCallBack) ( ptrInstance->MixerStream[0].pCallbackHandle, ptrInstance->MixerStream[0].pGeneralPurpose,ptrInstance->MixerStream[0].CallbackParam );
179 }
180 }
181 }
182
183 }
184 #endif
185 /**********************************************************************************/
186