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