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 "LVM_Macros.h"
24 
25 /**********************************************************************************
26    FUNCTION LVCore_MIXSOFT_1ST_D16C31_WRA
27 ***********************************************************************************/
LVC_Core_MixInSoft_D16C31_SAT(LVMixer3_FLOAT_st * ptrInstance,const LVM_FLOAT * src,LVM_FLOAT * dst,LVM_INT16 n)28 void LVC_Core_MixInSoft_D16C31_SAT(LVMixer3_FLOAT_st *ptrInstance,
29                                    const LVM_FLOAT   *src,
30                                          LVM_FLOAT   *dst,
31                                          LVM_INT16   n)
32 {
33 
34     LVM_INT16   OutLoop;
35     LVM_INT16   InLoop;
36     LVM_INT32   ii,jj;
37     Mix_Private_FLOAT_st  *pInstance = (Mix_Private_FLOAT_st *)(ptrInstance->PrivateParams);
38     LVM_FLOAT   Delta = pInstance->Delta;
39     LVM_FLOAT   Current = pInstance->Current;
40     LVM_FLOAT   Target = pInstance->Target;
41     LVM_FLOAT   Temp;
42 
43     InLoop = (LVM_INT16)(n >> 2); /* Process per 4 samples */
44     OutLoop = (LVM_INT16)(n - (InLoop << 2));
45 
46     if(Current < Target){
47         if (OutLoop){
48             Temp = Current + Delta;
49             Current = Temp;
50             if (Current > Target)
51                 Current = Target;
52 
53            for (ii = OutLoop; ii != 0; ii--){
54                 Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT)*(src++) * Current));
55                 if (Temp > 1.0f)
56                     *dst++ = 1.0f;
57                 else if (Temp < -1.0f)
58                     *dst++ = -1.0f;
59                 else
60                     *dst++ = (LVM_FLOAT)Temp;
61             }
62         }
63 
64         for (ii = InLoop; ii != 0; ii--){
65             Temp = Current + Delta;
66             Current = Temp;
67             if (Current > Target)
68                 Current = Target;
69 
70             for (jj = 4; jj != 0 ; jj--){
71                 Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT)*(src++) * Current));
72                 if (Temp > 1.0f)
73                     *dst++ = 1.0f;
74                 else if (Temp < -1.0f)
75                     *dst++ = -1.0f;
76                 else
77                     *dst++ = (LVM_FLOAT)Temp;
78             }
79         }
80     }
81     else{
82         if (OutLoop){
83             Current -= Delta;
84             if (Current < Target)
85                 Current = Target;
86 
87             for (ii = OutLoop; ii != 0; ii--){
88                 Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT)*(src++) * Current));
89                 if (Temp > 1.0f)
90                     *dst++ = 1.0f;
91                 else if (Temp < -1.0f)
92                     *dst++ = -1.0f;
93                 else
94                     *dst++ = (LVM_FLOAT)Temp;
95             }
96         }
97 
98         for (ii = InLoop; ii != 0; ii--){
99             Current -= Delta;
100             if (Current < Target)
101                 Current = Target;
102 
103             for (jj = 4; jj != 0 ; jj--){
104                 Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT)*(src++) * Current));
105                 if (Temp > 1.0f)
106                     *dst++ = 1.0f;
107                 else if (Temp < -1.0f)
108                     *dst++ = -1.0f;
109                 else
110                     *dst++ = (LVM_FLOAT)Temp;
111             }
112         }
113     }
114     pInstance->Current = Current;
115 }
116 #ifdef SUPPORT_MC
117 /*
118  * FUNCTION:       LVC_Core_MixInSoft_Mc_D16C31_SAT
119  *
120  * DESCRIPTION:
121  *  Mixer function with support for processing multichannel input.
122  *
123  * PARAMETERS:
124  *  ptrInstance    Instance pointer
125  *  src            Source
126  *  dst            Destination
127  *  NrFrames       Number of frames
128  *  NrChannels     Number of channels
129  *
130  * RETURNS:
131  *  void
132  *
133  */
LVC_Core_MixInSoft_Mc_D16C31_SAT(LVMixer3_FLOAT_st * ptrInstance,const LVM_FLOAT * src,LVM_FLOAT * dst,LVM_INT16 NrFrames,LVM_INT16 NrChannels)134 void LVC_Core_MixInSoft_Mc_D16C31_SAT(LVMixer3_FLOAT_st *ptrInstance,
135                                       const LVM_FLOAT   *src,
136                                             LVM_FLOAT   *dst,
137                                             LVM_INT16   NrFrames,
138                                             LVM_INT16   NrChannels)
139 {
140 
141     LVM_INT16   OutLoop;
142     LVM_INT16   InLoop;
143     LVM_INT32   ii, jj;
144     Mix_Private_FLOAT_st  *pInstance = (Mix_Private_FLOAT_st *)(ptrInstance->PrivateParams);
145     LVM_FLOAT   Delta = pInstance->Delta;
146     LVM_FLOAT   Current = pInstance->Current;
147     LVM_FLOAT   Target = pInstance->Target;
148     LVM_FLOAT   Temp;
149 
150     /*
151      * Same operation is performed on consecutive frames.
152      * So two frames are processed in one iteration and
153      * the loop will run only for half the NrFrames value times.
154      */
155     InLoop = (LVM_INT16)(NrFrames >> 1);
156     /* OutLoop is calculated to handle cases where NrFrames value can be odd.*/
157     OutLoop = (LVM_INT16)(NrFrames - (InLoop << 1));
158 
159     if (Current < Target) {
160         if (OutLoop) {
161             Temp = Current + Delta;
162             Current = Temp;
163             if (Current > Target)
164                 Current = Target;
165 
166            for (ii = OutLoop*NrChannels; ii != 0; ii--) {
167                 Temp = (*dst) + (*(src++) * Current);
168                 if (Temp > 1.0f)
169                     *dst++ = 1.0f;
170                 else if (Temp < -1.0f)
171                     *dst++ = -1.0f;
172                 else
173                     *dst++ = Temp;
174             }
175         }
176 
177         for (ii = InLoop; ii != 0; ii--) {
178             Temp = Current + Delta;
179             Current = Temp;
180             if (Current > Target)
181                 Current = Target;
182 
183             for (jj = NrChannels; jj != 0 ; jj--) {
184                 Temp = (*dst) + (*(src++) * Current);
185                 if (Temp > 1.0f)
186                     *dst++ = 1.0f;
187                 else if (Temp < -1.0f)
188                     *dst++ = -1.0f;
189                 else
190                     *dst++ = Temp;
191 
192                 Temp = (*dst) + (*(src++) * Current);
193                 if (Temp > 1.0f)
194                     *dst++ = 1.0f;
195                 else if (Temp < -1.0f)
196                     *dst++ = -1.0f;
197                 else
198                     *dst++ = Temp;
199 
200             }
201         }
202     }
203     else{
204         if (OutLoop) {
205             Current -= Delta;
206             if (Current < Target)
207                 Current = Target;
208 
209             for (ii = OutLoop*NrChannels; ii != 0; ii--) {
210                 Temp = (*dst) + (*(src++) * Current);
211                 if (Temp > 1.0f)
212                     *dst++ = 1.0f;
213                 else if (Temp < -1.0f)
214                     *dst++ = -1.0f;
215                 else
216                     *dst++ = Temp;
217             }
218         }
219 
220         for (ii = InLoop; ii != 0; ii--) {
221             Current -= Delta;
222             if (Current < Target)
223                 Current = Target;
224 
225             for (jj = NrChannels; jj != 0 ; jj--) {
226                 Temp = (*dst) + (*(src++) * Current);
227                 if (Temp > 1.0f)
228                     *dst++ = 1.0f;
229                 else if (Temp < -1.0f)
230                     *dst++ = -1.0f;
231                 else
232                     *dst++ = Temp;
233 
234                 Temp = (*dst) + (*(src++) * Current);
235                 if (Temp > 1.0f)
236                     *dst++ = 1.0f;
237                 else if (Temp < -1.0f)
238                     *dst++ = -1.0f;
239                 else
240                     *dst++ = Temp;
241 
242             }
243         }
244     }
245     pInstance->Current = Current;
246 }
247 
248 #endif
249 /**********************************************************************************/
250