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