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***********************************************************************************/
28#ifdef BUILD_FLOAT
29void LVC_Core_MixInSoft_D16C31_SAT( LVMixer3_FLOAT_st *ptrInstance,
30                                    const LVM_FLOAT     *src,
31                                          LVM_FLOAT     *dst,
32                                          LVM_INT16     n)
33{
34
35    LVM_INT16   OutLoop;
36    LVM_INT16   InLoop;
37    LVM_INT32   ii,jj;
38    Mix_Private_FLOAT_st  *pInstance = (Mix_Private_FLOAT_st *)(ptrInstance->PrivateParams);
39    LVM_FLOAT   Delta = pInstance->Delta;
40    LVM_FLOAT   Current = pInstance->Current;
41    LVM_FLOAT   Target = pInstance->Target;
42    LVM_FLOAT   Temp;
43
44    InLoop = (LVM_INT16)(n >> 2); /* Process per 4 samples */
45    OutLoop = (LVM_INT16)(n - (InLoop << 2));
46
47    if(Current < Target){
48        if (OutLoop){
49            Temp = Current + Delta;
50            Current = Temp;
51            if (Current > Target)
52                Current = Target;
53
54           for (ii = OutLoop; ii != 0; ii--){
55                Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT)*(src++) * Current));
56                if (Temp > 1.0f)
57                    *dst++ = 1.0f;
58                else if (Temp < -1.0f)
59                    *dst++ = -1.0f;
60                else
61                    *dst++ = (LVM_FLOAT)Temp;
62            }
63        }
64
65        for (ii = InLoop; ii != 0; ii--){
66            Temp = Current + Delta;
67            Current = Temp;
68            if (Current > Target)
69                Current = Target;
70
71            for (jj = 4; jj != 0 ; jj--){
72                Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT)*(src++) * Current));
73                if (Temp > 1.0f)
74                    *dst++ = 1.0f;
75                else if (Temp < -1.0f)
76                    *dst++ = -1.0f;
77                else
78                    *dst++ = (LVM_FLOAT)Temp;
79            }
80        }
81    }
82    else{
83        if (OutLoop){
84            Current -= Delta;
85            if (Current < Target)
86                Current = Target;
87
88            for (ii = OutLoop; ii != 0; ii--){
89                Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT)*(src++) * Current));
90                if (Temp > 1.0f)
91                    *dst++ = 1.0f;
92                else if (Temp < -1.0f)
93                    *dst++ = -1.0f;
94                else
95                    *dst++ = (LVM_FLOAT)Temp;
96            }
97        }
98
99        for (ii = InLoop; ii != 0; ii--){
100            Current -= Delta;
101            if (Current < Target)
102                Current = Target;
103
104            for (jj = 4; jj != 0 ; jj--){
105                Temp = ((LVM_FLOAT)*dst) + (((LVM_FLOAT)*(src++) * Current));
106                if (Temp > 1.0f)
107                    *dst++ = 1.0f;
108                else if (Temp < -1.0f)
109                    *dst++ = -1.0f;
110                else
111                    *dst++ = (LVM_FLOAT)Temp;
112            }
113        }
114    }
115    pInstance->Current = Current;
116}
117#else
118void LVC_Core_MixInSoft_D16C31_SAT( LVMixer3_st *ptrInstance,
119                                    const LVM_INT16     *src,
120                                          LVM_INT16     *dst,
121                                          LVM_INT16     n)
122{
123
124    LVM_INT16   OutLoop;
125    LVM_INT16   InLoop;
126    LVM_INT16   CurrentShort;
127    LVM_INT32   ii,jj;
128    Mix_Private_st  *pInstance=(Mix_Private_st *)(ptrInstance->PrivateParams);
129    LVM_INT32   Delta=pInstance->Delta;
130    LVM_INT32   Current=pInstance->Current;
131    LVM_INT32   Target=pInstance->Target;
132    LVM_INT32   Temp;
133
134    InLoop = (LVM_INT16)(n >> 2); /* Process per 4 samples */
135    OutLoop = (LVM_INT16)(n - (InLoop << 2));
136
137    if(Current<Target){
138        if (OutLoop){
139            ADD2_SAT_32x32(Current,Delta,Temp);                                      /* Q31 + Q31 into Q31*/
140            Current=Temp;
141            if (Current > Target)
142                Current = Target;
143
144            CurrentShort = (LVM_INT16)(Current>>16);                                 /* From Q31 to Q15*/
145
146            for (ii = OutLoop; ii != 0; ii--){
147                Temp = ((LVM_INT32)*dst) + (((LVM_INT32)*(src++) * CurrentShort)>>15);      /* Q15 + Q15*Q15>>15 into Q15 */
148                if (Temp > 0x00007FFF)
149                    *dst++ = 0x7FFF;
150                else if (Temp < -0x00008000)
151                    *dst++ = - 0x8000;
152                else
153                    *dst++ = (LVM_INT16)Temp;
154            }
155        }
156
157        for (ii = InLoop; ii != 0; ii--){
158            ADD2_SAT_32x32(Current,Delta,Temp);                                      /* Q31 + Q31 into Q31*/
159            Current=Temp;
160            if (Current > Target)
161                Current = Target;
162
163            CurrentShort = (LVM_INT16)(Current>>16);                                 /* From Q31 to Q15*/
164
165            for (jj = 4; jj!=0 ; jj--){
166                Temp = ((LVM_INT32)*dst) + (((LVM_INT32)*(src++) * CurrentShort)>>15);      /* Q15 + Q15*Q15>>15 into Q15 */
167                if (Temp > 0x00007FFF)
168                    *dst++ = 0x7FFF;
169                else if (Temp < -0x00008000)
170                    *dst++ = - 0x8000;
171                else
172                    *dst++ = (LVM_INT16)Temp;
173            }
174        }
175    }
176    else{
177        if (OutLoop){
178            Current -= Delta;                                                        /* Q31 + Q31 into Q31*/
179            if (Current < Target)
180                Current = Target;
181
182            CurrentShort = (LVM_INT16)(Current>>16);                                 /* From Q31 to Q15*/
183
184            for (ii = OutLoop; ii != 0; ii--){
185                Temp = ((LVM_INT32)*dst) + (((LVM_INT32)*(src++) * CurrentShort)>>15);      /* Q15 + Q15*Q15>>15 into Q15 */
186                if (Temp > 0x00007FFF)
187                    *dst++ = 0x7FFF;
188                else if (Temp < -0x00008000)
189                    *dst++ = - 0x8000;
190                else
191                    *dst++ = (LVM_INT16)Temp;
192            }
193        }
194
195        for (ii = InLoop; ii != 0; ii--){
196            Current -= Delta;                                                        /* Q31 + Q31 into Q31*/
197            if (Current < Target)
198                Current = Target;
199
200            CurrentShort = (LVM_INT16)(Current>>16);                                 /* From Q31 to Q15*/
201
202            for (jj = 4; jj!=0 ; jj--){
203                Temp = ((LVM_INT32)*dst) + (((LVM_INT32)*(src++) * CurrentShort)>>15);      /* Q15 + Q15*Q15>>15 into Q15 */
204                if (Temp > 0x00007FFF)
205                    *dst++ = 0x7FFF;
206                else if (Temp < -0x00008000)
207                    *dst++ = - 0x8000;
208                else
209                    *dst++ = (LVM_INT16)Temp;
210            }
211        }
212    }
213    pInstance->Current=Current;
214}
215#endif
216/**********************************************************************************/
217