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 #include "ScalarArithmetic.h" 25 26 /********************************************************************************** 27 FUNCTION LVCore_MIXSOFT_1ST_D16C31_WRA 28 ***********************************************************************************/ 29 #ifdef BUILD_FLOAT 30 void LVC_Core_MixSoft_1St_D16C31_WRA( LVMixer3_FLOAT_st *ptrInstance, 31 const LVM_FLOAT *src, 32 LVM_FLOAT *dst, 33 LVM_INT16 n) 34 { 35 LVM_INT16 OutLoop; 36 LVM_INT16 InLoop; 37 LVM_INT32 ii; 38 Mix_Private_FLOAT_st *pInstance=(Mix_Private_FLOAT_st *)(ptrInstance->PrivateParams); 39 LVM_FLOAT Delta= (LVM_FLOAT)pInstance->Delta; 40 LVM_FLOAT Current = (LVM_FLOAT)pInstance->Current; 41 LVM_FLOAT Target= (LVM_FLOAT)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 50 Temp = Current + Delta; 51 if (Temp > 1.0f) 52 Temp = 1.0f; 53 else if (Temp < -1.0f) 54 Temp = -1.0f; 55 56 Current=Temp; 57 if (Current > Target) 58 Current = Target; 59 60 for (ii = OutLoop; ii != 0; ii--){ 61 *(dst++) = (((LVM_FLOAT)*(src++) * (LVM_FLOAT)Current)); 62 } 63 } 64 65 for (ii = InLoop; ii != 0; ii--){ 66 67 Temp = Current + Delta; 68 69 if (Temp > 1.0f) 70 Temp = 1.0f; 71 else if (Temp < -1.0f) 72 Temp = -1.0f; 73 74 Current=Temp; 75 if (Current > Target) 76 Current = Target; 77 78 *(dst++) = (((LVM_FLOAT)*(src++) * Current) ); 79 *(dst++) = (((LVM_FLOAT)*(src++) * Current) ); 80 *(dst++) = (((LVM_FLOAT)*(src++) * Current) ); 81 *(dst++) = (((LVM_FLOAT)*(src++) * Current) ); 82 } 83 } 84 else{ 85 if (OutLoop){ 86 Current -= Delta; 87 if (Current < Target) 88 Current = Target; 89 90 for (ii = OutLoop; ii != 0; ii--){ 91 *(dst++) = (((LVM_FLOAT)*(src++) * Current)); 92 } 93 } 94 95 for (ii = InLoop; ii != 0; ii--){ 96 Current -= Delta; 97 if (Current < Target) 98 Current = Target; 99 100 *(dst++) = (((LVM_FLOAT)*(src++) * Current)); 101 *(dst++) = (((LVM_FLOAT)*(src++) * Current)); 102 *(dst++) = (((LVM_FLOAT)*(src++) * Current)); 103 *(dst++) = (((LVM_FLOAT)*(src++) * Current)); 104 } 105 } 106 pInstance->Current=Current; 107 } 108 #else 109 void LVC_Core_MixSoft_1St_D16C31_WRA( LVMixer3_st *ptrInstance, 110 const LVM_INT16 *src, 111 LVM_INT16 *dst, 112 LVM_INT16 n) 113 { 114 LVM_INT16 OutLoop; 115 LVM_INT16 InLoop; 116 LVM_INT16 CurrentShort; 117 LVM_INT32 ii; 118 Mix_Private_st *pInstance=(Mix_Private_st *)(ptrInstance->PrivateParams); 119 LVM_INT32 Delta=pInstance->Delta; 120 LVM_INT32 Current=pInstance->Current; 121 LVM_INT32 Target=pInstance->Target; 122 LVM_INT32 Temp; 123 124 InLoop = (LVM_INT16)(n >> 2); /* Process per 4 samples */ 125 OutLoop = (LVM_INT16)(n - (InLoop << 2)); 126 127 if(Current<Target){ 128 if (OutLoop){ 129 ADD2_SAT_32x32(Current,Delta,Temp); /* Q31 + Q31 into Q31*/ 130 Current=Temp; 131 if (Current > Target) 132 Current = Target; 133 134 CurrentShort = (LVM_INT16)(Current>>16); /* From Q31 to Q15*/ 135 136 for (ii = OutLoop; ii != 0; ii--){ 137 *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShort)>>15); /* Q15*Q15>>15 into Q15 */ 138 } 139 } 140 141 for (ii = InLoop; ii != 0; ii--){ 142 ADD2_SAT_32x32(Current,Delta,Temp); /* Q31 + Q31 into Q31*/ 143 Current=Temp; 144 if (Current > Target) 145 Current = Target; 146 147 CurrentShort = (LVM_INT16)(Current>>16); /* From Q31 to Q15*/ 148 149 *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShort)>>15); /* Q15*Q15>>15 into Q15 */ 150 *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShort)>>15); 151 *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShort)>>15); 152 *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShort)>>15); 153 } 154 } 155 else{ 156 if (OutLoop){ 157 Current -= Delta; /* Q31 + Q31 into Q31*/ 158 if (Current < Target) 159 Current = Target; 160 161 CurrentShort = (LVM_INT16)(Current>>16); /* From Q31 to Q15*/ 162 163 for (ii = OutLoop; ii != 0; ii--){ 164 *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShort)>>15); /* Q15*Q15>>15 into Q15 */ 165 } 166 } 167 168 for (ii = InLoop; ii != 0; ii--){ 169 Current -= Delta; /* Q31 + Q31 into Q31*/ 170 if (Current < Target) 171 Current = Target; 172 173 CurrentShort = (LVM_INT16)(Current>>16); /* From Q31 to Q15*/ 174 175 *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShort)>>15); /* Q15*Q15>>15 into Q15 */ 176 *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShort)>>15); 177 *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShort)>>15); 178 *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShort)>>15); 179 } 180 } 181 pInstance->Current=Current; 182 } 183 #endif 184 /**********************************************************************************/ 185