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 ***********************************************************************************/
LVC_MixSoft_1St_D16C31_SAT(LVMixer3_1St_FLOAT_st * ptrInstance,const LVM_FLOAT * src,LVM_FLOAT * dst,LVM_INT16 n)36 void LVC_MixSoft_1St_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_MixSoft_1St_D16C31_WRA(&(ptrInstance->MixerStream[0]), src, dst, n);
66         }
67     }
68 
69     /******************************************************************************
70        HARD MIXING
71     *******************************************************************************/
72 
73     if (HardMixing){
74         if (pInstance->Target == 0)
75             LoadConst_Float(0.0, dst, n);
76         else {
77             if ((pInstance->Target) != 1.0f)
78                 Mult3s_Float(src, (pInstance->Target), dst, n);
79             else if(src != dst)
80                 Copy_Float(src, dst, n);
81         }
82 
83     }
84 
85     /******************************************************************************
86        CALL BACK
87     *******************************************************************************/
88 
89     if (ptrInstance->MixerStream[0].CallbackSet){
90         if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta){
91             pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
92                                                        Make them equal. */
93             TargetGain = pInstance->Target;
94             LVC_Mixer_SetTarget(ptrInstance->MixerStream, TargetGain);
95             ptrInstance->MixerStream[0].CallbackSet = FALSE;
96             if (ptrInstance->MixerStream[0].pCallBack != 0){
97                 (*ptrInstance->MixerStream[0].pCallBack) ( \
98                                                 ptrInstance->MixerStream[0].pCallbackHandle,
99                                                 ptrInstance->MixerStream[0].pGeneralPurpose,
100                                                 ptrInstance->MixerStream[0].CallbackParam );
101             }
102         }
103     }
104 }
105 #ifdef SUPPORT_MC
106 /*
107  * FUNCTION:       LVC_MixSoft_Mc_D16C31_SAT
108  *
109  * DESCRIPTION:
110  *  Mixer function with support for processing multichannel input
111  *
112  * PARAMETERS:
113  *  ptrInstance    Instance pointer
114  *  src            Source
115  *  dst            Destination
116  *  NrFrames       Number of Frames
117  *  NrChannels     Number of channels
118  *
119  * RETURNS:
120  *  void
121  *
122  */
LVC_MixSoft_Mc_D16C31_SAT(LVMixer3_1St_FLOAT_st * ptrInstance,const LVM_FLOAT * src,LVM_FLOAT * dst,LVM_INT16 NrFrames,LVM_INT16 NrChannels)123 void LVC_MixSoft_Mc_D16C31_SAT(LVMixer3_1St_FLOAT_st *ptrInstance,
124                                   const LVM_FLOAT      *src,
125                                         LVM_FLOAT      *dst,
126                                         LVM_INT16      NrFrames,
127                                         LVM_INT16      NrChannels)
128 {
129     char        HardMixing = TRUE;
130     LVM_FLOAT   TargetGain;
131     Mix_Private_FLOAT_st  *pInstance = \
132                           (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[0].PrivateParams);
133 
134     if (NrFrames <= 0)    return;
135 
136     /******************************************************************************
137        SOFT MIXING
138     *******************************************************************************/
139     if (pInstance->Current != pInstance->Target)
140     {
141         if (pInstance->Delta == 1.0f) {
142             pInstance->Current = pInstance->Target;
143             TargetGain = pInstance->Target;
144             LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
145         }else if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta) {
146             pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
147                                                        Make them equal. */
148             TargetGain = pInstance->Target;
149             LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain);
150         }else{
151             /* Soft mixing has to be applied */
152             HardMixing = FALSE;
153             LVC_Core_MixSoft_Mc_D16C31_WRA(&(ptrInstance->MixerStream[0]),
154                                            src,
155                                            dst,
156                                            NrFrames,
157                                            NrChannels);
158         }
159     }
160 
161     /******************************************************************************
162        HARD MIXING
163     *******************************************************************************/
164 
165     if (HardMixing) {
166         if (pInstance->Target == 0)
167             LoadConst_Float(0.0, dst, NrFrames * NrChannels);
168         else {
169             if ((pInstance->Target) != 1.0f)
170                 Mult3s_Float(src, (pInstance->Target), dst, NrFrames * NrChannels);
171             else if (src != dst)
172                 Copy_Float(src, dst, NrFrames * NrChannels);
173         }
174 
175     }
176 
177     /******************************************************************************
178        CALL BACK
179     *******************************************************************************/
180 
181     if (ptrInstance->MixerStream[0].CallbackSet) {
182         if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta) {
183             pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \
184                                                        Make them equal. */
185             TargetGain = pInstance->Target;
186             LVC_Mixer_SetTarget(ptrInstance->MixerStream, TargetGain);
187             ptrInstance->MixerStream[0].CallbackSet = FALSE;
188             if (ptrInstance->MixerStream[0].pCallBack != 0) {
189                 (*ptrInstance->MixerStream[0].pCallBack) (\
190                                                 ptrInstance->MixerStream[0].pCallbackHandle,
191                                                 ptrInstance->MixerStream[0].pGeneralPurpose,
192                                                 ptrInstance->MixerStream[0].CallbackParam);
193             }
194         }
195     }
196 }
197 
198 #endif
199 
200 /**********************************************************************************/
201