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 ***********************************************************************************/
LVC_MixInSoft_D16C31_SAT(LVMixer3_1St_FLOAT_st * ptrInstance,const LVM_FLOAT * src,LVM_FLOAT * dst,LVM_INT16 n)36 void LVC_MixInSoft_D16C31_SAT(LVMixer3_1St_FLOAT_st *ptrInstance,
37                               const LVM_FLOAT       *src,
38                                     LVM_FLOAT       *dst,
39                                     LVM_INT16       n)
40 {
41     char        HardMixing = TRUE;
42     LVM_FLOAT   TargetGain;
43     Mix_Private_FLOAT_st  *pInstance = \
44                              (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[0].PrivateParams);
45 
46     if(n <= 0)    return;
47 
48     /******************************************************************************
49        SOFT MIXING
50     *******************************************************************************/
51     if (pInstance->Current != pInstance->Target)
52     {
53         if(pInstance->Delta == 1.0f){
54             pInstance->Current = pInstance->Target;
55             TargetGain = pInstance->Target;
56             LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
57         }else if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta){
58             pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
59                                                        Make them equal. */
60             TargetGain = pInstance->Target;
61             LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
62         }else{
63             /* Soft mixing has to be applied */
64             HardMixing = FALSE;
65             LVC_Core_MixInSoft_D16C31_SAT(&(ptrInstance->MixerStream[0]), src, dst, n);
66         }
67     }
68 
69     /******************************************************************************
70        HARD MIXING
71     *******************************************************************************/
72 
73     if (HardMixing){
74         if (pInstance->Target != 0){ /* Nothing to do in case Target = 0 */
75             if ((pInstance->Target) == 1.0f){
76                 Add2_Sat_Float(src, dst, n);
77             }
78             else{
79                 Mac3s_Sat_Float(src, (pInstance->Target), dst, n);
80                 /* In case the LVCore function would have changed the Current value */
81                 pInstance->Current = pInstance->Target;
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 }
107 
108 #ifdef SUPPORT_MC
109 /*
110  * FUNCTION:       LVC_MixInSoft_Mc_D16C31_SAT
111  *
112  * DESCRIPTION:
113  *  Mixer function with support for processing multichannel input
114  *
115  * PARAMETERS:
116  *  ptrInstance    Instance pointer
117  *  src            Source
118  *  dst            Destination
119  *  NrFrames       Number of frames
120  *  NrChannels     Number of channels
121  *
122  * RETURNS:
123  *  void
124  *
125  */
LVC_MixInSoft_Mc_D16C31_SAT(LVMixer3_1St_FLOAT_st * ptrInstance,const LVM_FLOAT * src,LVM_FLOAT * dst,LVM_INT16 NrFrames,LVM_INT16 NrChannels)126 void LVC_MixInSoft_Mc_D16C31_SAT(LVMixer3_1St_FLOAT_st *ptrInstance,
127                                  const LVM_FLOAT       *src,
128                                        LVM_FLOAT       *dst,
129                                        LVM_INT16       NrFrames,
130                                        LVM_INT16       NrChannels)
131 {
132     char        HardMixing = TRUE;
133     LVM_FLOAT   TargetGain;
134     Mix_Private_FLOAT_st  *pInstance = \
135                              (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[0].PrivateParams);
136 
137     if (NrFrames <= 0)    return;
138 
139     /******************************************************************************
140        SOFT MIXING
141     *******************************************************************************/
142     if (pInstance->Current != pInstance->Target)
143     {
144         if (pInstance->Delta == 1.0f) {
145             pInstance->Current = pInstance->Target;
146             TargetGain = pInstance->Target;
147             LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
148         }else if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta) {
149             pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
150                                                        Make them equal. */
151             TargetGain = pInstance->Target;
152             LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
153         }else{
154             /* Soft mixing has to be applied */
155             HardMixing = FALSE;
156             LVC_Core_MixInSoft_Mc_D16C31_SAT(&(ptrInstance->MixerStream[0]),
157                                              src,
158                                              dst,
159                                              NrFrames,
160                                              NrChannels);
161         }
162     }
163 
164     /******************************************************************************
165        HARD MIXING
166     *******************************************************************************/
167 
168     if (HardMixing) {
169         if (pInstance->Target != 0) { /* Nothing to do in case Target = 0 */
170             if ((pInstance->Target) == 1.0f) {
171                 Add2_Sat_Float(src, dst, NrFrames*NrChannels);
172             }
173             else{
174                 Mac3s_Sat_Float(src,
175                                 (pInstance->Target),
176                                 dst,
177                                 NrFrames * NrChannels);
178                 /* In case the LVCore function would have changed the Current value */
179                 pInstance->Current = pInstance->Target;
180             }
181         }
182     }
183 
184     /******************************************************************************
185        CALL BACK
186     *******************************************************************************/
187 
188     if (ptrInstance->MixerStream[0].CallbackSet) {
189         if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta) {
190             pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
191                                                        Make them equal. */
192             TargetGain = pInstance->Target;
193             LVC_Mixer_SetTarget(ptrInstance->MixerStream, TargetGain);
194             ptrInstance->MixerStream[0].CallbackSet = FALSE;
195             if (ptrInstance->MixerStream[0].pCallBack != 0) {
196                 (*ptrInstance->MixerStream[0].pCallBack) (\
197                                                 ptrInstance->MixerStream[0].pCallbackHandle,
198                                                 ptrInstance->MixerStream[0].pGeneralPurpose,
199                                                 ptrInstance->MixerStream[0].CallbackParam);
200             }
201         }
202     }
203 
204 }
205 #endif
206 
207 /**********************************************************************************/
208