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 "ScalarArithmetic.h" 24 #include "LVM_Macros.h" 25 26 /********************************************************************************** 27 FUNCTION LVC_Core_MixSoft_1St_2i_D16C31_WRA 28 ***********************************************************************************/ 29 #ifdef BUILD_FLOAT 30 static LVM_FLOAT ADD2_SAT_FLOAT(LVM_FLOAT a, 31 LVM_FLOAT b, 32 LVM_FLOAT c) 33 { 34 LVM_FLOAT temp; 35 temp = a + b ; 36 if (temp < -1.0f) 37 c = -1.0f; 38 else if (temp > 1.0f) 39 c = 1.0f; 40 else 41 c = temp; 42 return c; 43 } 44 void LVC_Core_MixSoft_1St_2i_D16C31_WRA( LVMixer3_FLOAT_st *ptrInstance1, 45 LVMixer3_FLOAT_st *ptrInstance2, 46 const LVM_FLOAT *src, 47 LVM_FLOAT *dst, 48 LVM_INT16 n) 49 { 50 LVM_INT16 OutLoop; 51 LVM_INT16 InLoop; 52 LVM_INT32 ii; 53 Mix_Private_FLOAT_st *pInstanceL = (Mix_Private_FLOAT_st *)(ptrInstance1->PrivateParams); 54 Mix_Private_FLOAT_st *pInstanceR = (Mix_Private_FLOAT_st *)(ptrInstance2->PrivateParams); 55 56 LVM_FLOAT DeltaL = pInstanceL->Delta; 57 LVM_FLOAT CurrentL = pInstanceL->Current; 58 LVM_FLOAT TargetL = pInstanceL->Target; 59 60 LVM_FLOAT DeltaR = pInstanceR->Delta; 61 LVM_FLOAT CurrentR = pInstanceR->Current; 62 LVM_FLOAT TargetR = pInstanceR->Target; 63 64 LVM_FLOAT Temp = 0; 65 66 InLoop = (LVM_INT16)(n >> 2); /* Process per 4 samples */ 67 OutLoop = (LVM_INT16)(n - (InLoop << 2)); 68 69 if (OutLoop) 70 { 71 if(CurrentL < TargetL) 72 { 73 ADD2_SAT_FLOAT(CurrentL, DeltaL, Temp); 74 CurrentL = Temp; 75 if (CurrentL > TargetL) 76 CurrentL = TargetL; 77 } 78 else 79 { 80 CurrentL -= DeltaL; 81 if (CurrentL < TargetL) 82 CurrentL = TargetL; 83 } 84 85 if(CurrentR < TargetR) 86 { 87 ADD2_SAT_FLOAT(CurrentR, DeltaR, Temp); 88 CurrentR = Temp; 89 if (CurrentR > TargetR) 90 CurrentR = TargetR; 91 } 92 else 93 { 94 CurrentR -= DeltaR; 95 if (CurrentR < TargetR) 96 CurrentR = TargetR; 97 } 98 99 for (ii = OutLoop * 2; ii != 0; ii -= 2) 100 { 101 *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentL)); 102 *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentR)); 103 } 104 } 105 106 for (ii = InLoop * 2; ii != 0; ii-=2) 107 { 108 if(CurrentL < TargetL) 109 { 110 ADD2_SAT_FLOAT(CurrentL, DeltaL, Temp); 111 CurrentL = Temp; 112 if (CurrentL > TargetL) 113 CurrentL = TargetL; 114 } 115 else 116 { 117 CurrentL -= DeltaL; 118 if (CurrentL < TargetL) 119 CurrentL = TargetL; 120 } 121 122 if(CurrentR < TargetR) 123 { 124 ADD2_SAT_FLOAT(CurrentR, DeltaR, Temp); 125 CurrentR = Temp; 126 if (CurrentR > TargetR) 127 CurrentR = TargetR; 128 } 129 else 130 { 131 CurrentR -= DeltaR; 132 if (CurrentR < TargetR) 133 CurrentR = TargetR; 134 } 135 136 *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentL)); 137 *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentR)); 138 *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentL)); 139 *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentR)); 140 *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentL)); 141 *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentR)); 142 *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentL)); 143 *(dst++) = (LVM_FLOAT)(((LVM_FLOAT)*(src++) * (LVM_FLOAT)CurrentR)); 144 } 145 pInstanceL->Current = CurrentL; 146 pInstanceR->Current = CurrentR; 147 148 } 149 #ifdef SUPPORT_MC 150 void LVC_Core_MixSoft_1St_MC_float_WRA (Mix_Private_FLOAT_st **ptrInstance, 151 const LVM_FLOAT *src, 152 LVM_FLOAT *dst, 153 LVM_INT16 NrFrames, 154 LVM_INT16 NrChannels) 155 { 156 LVM_INT32 ii, ch; 157 LVM_FLOAT Temp =0.0f; 158 LVM_FLOAT tempCurrent[NrChannels]; 159 for (ch = 0; ch < NrChannels; ch++) 160 { 161 tempCurrent[ch] = ptrInstance[ch]->Current; 162 } 163 for (ii = NrFrames; ii > 0; ii--) 164 { 165 for (ch = 0; ch < NrChannels; ch++) 166 { 167 Mix_Private_FLOAT_st *pInstance = ptrInstance[ch]; 168 const LVM_FLOAT Delta = pInstance->Delta; 169 LVM_FLOAT Current = tempCurrent[ch]; 170 const LVM_FLOAT Target = pInstance->Target; 171 if (Current < Target) 172 { 173 ADD2_SAT_FLOAT(Current, Delta, Temp); 174 Current = Temp; 175 if (Current > Target) 176 Current = Target; 177 } 178 else 179 { 180 Current -= Delta; 181 if (Current < Target) 182 Current = Target; 183 } 184 *dst++ = *src++ * Current; 185 tempCurrent[ch] = Current; 186 } 187 } 188 for (ch = 0; ch < NrChannels; ch++) 189 { 190 ptrInstance[ch]->Current = tempCurrent[ch]; 191 } 192 } 193 #endif 194 #else 195 void LVC_Core_MixSoft_1St_2i_D16C31_WRA( LVMixer3_st *ptrInstance1, 196 LVMixer3_st *ptrInstance2, 197 const LVM_INT16 *src, 198 LVM_INT16 *dst, 199 LVM_INT16 n) 200 { 201 LVM_INT16 OutLoop; 202 LVM_INT16 InLoop; 203 LVM_INT16 CurrentShortL; 204 LVM_INT16 CurrentShortR; 205 LVM_INT32 ii; 206 Mix_Private_st *pInstanceL=(Mix_Private_st *)(ptrInstance1->PrivateParams); 207 Mix_Private_st *pInstanceR=(Mix_Private_st *)(ptrInstance2->PrivateParams); 208 209 LVM_INT32 DeltaL=pInstanceL->Delta; 210 LVM_INT32 CurrentL=pInstanceL->Current; 211 LVM_INT32 TargetL=pInstanceL->Target; 212 213 LVM_INT32 DeltaR=pInstanceR->Delta; 214 LVM_INT32 CurrentR=pInstanceR->Current; 215 LVM_INT32 TargetR=pInstanceR->Target; 216 217 LVM_INT32 Temp; 218 219 InLoop = (LVM_INT16)(n >> 2); /* Process per 4 samples */ 220 OutLoop = (LVM_INT16)(n - (InLoop << 2)); 221 222 if (OutLoop) 223 { 224 if(CurrentL<TargetL) 225 { 226 ADD2_SAT_32x32(CurrentL,DeltaL,Temp); /* Q31 + Q31 into Q31*/ 227 CurrentL=Temp; 228 if (CurrentL > TargetL) 229 CurrentL = TargetL; 230 } 231 else 232 { 233 CurrentL -= DeltaL; /* Q31 + Q31 into Q31*/ 234 if (CurrentL < TargetL) 235 CurrentL = TargetL; 236 } 237 238 if(CurrentR<TargetR) 239 { 240 ADD2_SAT_32x32(CurrentR,DeltaR,Temp); /* Q31 + Q31 into Q31*/ 241 CurrentR=Temp; 242 if (CurrentR > TargetR) 243 CurrentR = TargetR; 244 } 245 else 246 { 247 CurrentR -= DeltaR; /* Q31 + Q31 into Q31*/ 248 if (CurrentR < TargetR) 249 CurrentR = TargetR; 250 } 251 252 CurrentShortL = (LVM_INT16)(CurrentL>>16); /* From Q31 to Q15*/ 253 CurrentShortR = (LVM_INT16)(CurrentR>>16); /* From Q31 to Q15*/ 254 255 for (ii = OutLoop*2; ii != 0; ii-=2) 256 { 257 *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShortL)>>15); /* Q15*Q15>>15 into Q15 */ 258 *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShortR)>>15); /* Q15*Q15>>15 into Q15 */ 259 } 260 } 261 262 for (ii = InLoop*2; ii != 0; ii-=2) 263 { 264 if(CurrentL<TargetL) 265 { 266 ADD2_SAT_32x32(CurrentL,DeltaL,Temp); /* Q31 + Q31 into Q31*/ 267 CurrentL=Temp; 268 if (CurrentL > TargetL) 269 CurrentL = TargetL; 270 } 271 else 272 { 273 CurrentL -= DeltaL; /* Q31 + Q31 into Q31*/ 274 if (CurrentL < TargetL) 275 CurrentL = TargetL; 276 } 277 278 if(CurrentR<TargetR) 279 { 280 ADD2_SAT_32x32(CurrentR,DeltaR,Temp); /* Q31 + Q31 into Q31*/ 281 CurrentR=Temp; 282 if (CurrentR > TargetR) 283 CurrentR = TargetR; 284 } 285 else 286 { 287 CurrentR -= DeltaR; /* Q31 + Q31 into Q31*/ 288 if (CurrentR < TargetR) 289 CurrentR = TargetR; 290 } 291 292 CurrentShortL = (LVM_INT16)(CurrentL>>16); /* From Q31 to Q15*/ 293 CurrentShortR = (LVM_INT16)(CurrentR>>16); /* From Q31 to Q15*/ 294 295 *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShortL)>>15); /* Q15*Q15>>15 into Q15 */ 296 *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShortR)>>15); /* Q15*Q15>>15 into Q15 */ 297 *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShortL)>>15); 298 *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShortR)>>15); 299 *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShortL)>>15); 300 *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShortR)>>15); 301 *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShortL)>>15); 302 *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShortR)>>15); 303 } 304 pInstanceL->Current=CurrentL; 305 pInstanceR->Current=CurrentR; 306 307 } 308 #endif 309 /**********************************************************************************/ 310