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 "VectorArithmetic.h" 24 #include "ScalarArithmetic.h" 25 26 /********************************************************************************** 27 DEFINITIONS 28 ***********************************************************************************/ 29 30 #define TRUE 1 31 #define FALSE 0 32 33 /********************************************************************************** 34 FUNCTION LVMixer3_MIXSOFT_1ST_D16C31_SAT 35 ***********************************************************************************/ 36 #ifdef BUILD_FLOAT 37 void LVC_MixSoft_1St_D16C31_SAT( LVMixer3_1St_FLOAT_st *ptrInstance, 38 const LVM_FLOAT *src, 39 LVM_FLOAT *dst, 40 LVM_INT16 n) 41 { 42 char HardMixing = TRUE; 43 LVM_FLOAT TargetGain; 44 Mix_Private_FLOAT_st *pInstance = \ 45 (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[0].PrivateParams); 46 47 if(n <= 0) return; 48 49 /****************************************************************************** 50 SOFT MIXING 51 *******************************************************************************/ 52 if (pInstance->Current != pInstance->Target) 53 { 54 if(pInstance->Delta == 1.0f){ 55 pInstance->Current = pInstance->Target; 56 TargetGain = pInstance->Target; 57 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain); 58 }else if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta){ 59 pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \ 60 Make them equal. */ 61 TargetGain = pInstance->Target; 62 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain); 63 }else{ 64 /* Soft mixing has to be applied */ 65 HardMixing = FALSE; 66 LVC_Core_MixSoft_1St_D16C31_WRA(&(ptrInstance->MixerStream[0]), src, dst, n); 67 } 68 } 69 70 /****************************************************************************** 71 HARD MIXING 72 *******************************************************************************/ 73 74 if (HardMixing){ 75 if (pInstance->Target == 0) 76 LoadConst_Float(0.0, dst, n); 77 else { 78 if ((pInstance->Target) != 1.0f) 79 Mult3s_Float(src, (pInstance->Target), dst, n); 80 else if(src != dst) 81 Copy_Float(src, dst, n); 82 } 83 84 } 85 86 /****************************************************************************** 87 CALL BACK 88 *******************************************************************************/ 89 90 if (ptrInstance->MixerStream[0].CallbackSet){ 91 if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta){ 92 pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \ 93 Make them equal. */ 94 TargetGain = pInstance->Target; 95 LVC_Mixer_SetTarget(ptrInstance->MixerStream, TargetGain); 96 ptrInstance->MixerStream[0].CallbackSet = FALSE; 97 if (ptrInstance->MixerStream[0].pCallBack != 0){ 98 (*ptrInstance->MixerStream[0].pCallBack) ( \ 99 ptrInstance->MixerStream[0].pCallbackHandle, 100 ptrInstance->MixerStream[0].pGeneralPurpose, 101 ptrInstance->MixerStream[0].CallbackParam ); 102 } 103 } 104 } 105 } 106 #ifdef SUPPORT_MC 107 /* 108 * FUNCTION: LVC_MixSoft_Mc_D16C31_SAT 109 * 110 * DESCRIPTION: 111 * Mixer function with support for processing multichannel input 112 * 113 * PARAMETERS: 114 * ptrInstance Instance pointer 115 * src Source 116 * dst Destination 117 * NrFrames Number of Frames 118 * NrChannels Number of channels 119 * 120 * RETURNS: 121 * void 122 * 123 */ 124 void LVC_MixSoft_Mc_D16C31_SAT(LVMixer3_1St_FLOAT_st *ptrInstance, 125 const LVM_FLOAT *src, 126 LVM_FLOAT *dst, 127 LVM_INT16 NrFrames, 128 LVM_INT16 NrChannels) 129 { 130 char HardMixing = TRUE; 131 LVM_FLOAT TargetGain; 132 Mix_Private_FLOAT_st *pInstance = \ 133 (Mix_Private_FLOAT_st *)(ptrInstance->MixerStream[0].PrivateParams); 134 135 if (NrFrames <= 0) return; 136 137 /****************************************************************************** 138 SOFT MIXING 139 *******************************************************************************/ 140 if (pInstance->Current != pInstance->Target) 141 { 142 if (pInstance->Delta == 1.0f) { 143 pInstance->Current = pInstance->Target; 144 TargetGain = pInstance->Target; 145 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain); 146 }else if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta) { 147 pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \ 148 Make them equal. */ 149 TargetGain = pInstance->Target; 150 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]), TargetGain); 151 }else{ 152 /* Soft mixing has to be applied */ 153 HardMixing = FALSE; 154 LVC_Core_MixSoft_Mc_D16C31_WRA(&(ptrInstance->MixerStream[0]), 155 src, 156 dst, 157 NrFrames, 158 NrChannels); 159 } 160 } 161 162 /****************************************************************************** 163 HARD MIXING 164 *******************************************************************************/ 165 166 if (HardMixing) { 167 if (pInstance->Target == 0) 168 LoadConst_Float(0.0, dst, NrFrames * NrChannels); 169 else { 170 if ((pInstance->Target) != 1.0f) 171 Mult3s_Float(src, (pInstance->Target), dst, NrFrames * NrChannels); 172 else if (src != dst) 173 Copy_Float(src, dst, NrFrames * NrChannels); 174 } 175 176 } 177 178 /****************************************************************************** 179 CALL BACK 180 *******************************************************************************/ 181 182 if (ptrInstance->MixerStream[0].CallbackSet) { 183 if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta) { 184 pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \ 185 Make them equal. */ 186 TargetGain = pInstance->Target; 187 LVC_Mixer_SetTarget(ptrInstance->MixerStream, TargetGain); 188 ptrInstance->MixerStream[0].CallbackSet = FALSE; 189 if (ptrInstance->MixerStream[0].pCallBack != 0) { 190 (*ptrInstance->MixerStream[0].pCallBack) (\ 191 ptrInstance->MixerStream[0].pCallbackHandle, 192 ptrInstance->MixerStream[0].pGeneralPurpose, 193 ptrInstance->MixerStream[0].CallbackParam); 194 } 195 } 196 } 197 } 198 199 #endif 200 201 #else 202 void LVC_MixSoft_1St_D16C31_SAT( LVMixer3_1St_st *ptrInstance, 203 const LVM_INT16 *src, 204 LVM_INT16 *dst, 205 LVM_INT16 n) 206 { 207 char HardMixing = TRUE; 208 LVM_INT32 TargetGain; 209 Mix_Private_st *pInstance=(Mix_Private_st *)(ptrInstance->MixerStream[0].PrivateParams); 210 211 if(n<=0) return; 212 213 /****************************************************************************** 214 SOFT MIXING 215 *******************************************************************************/ 216 if (pInstance->Current != pInstance->Target) 217 { 218 if(pInstance->Delta == 0x7FFFFFFF){ 219 pInstance->Current = pInstance->Target; 220 TargetGain=pInstance->Target>>(16-pInstance->Shift); // TargetGain in Q16.15 format 221 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]),TargetGain); 222 }else if (Abs_32(pInstance->Current-pInstance->Target) < pInstance->Delta){ 223 pInstance->Current = pInstance->Target; /* Difference is not significant anymore. Make them equal. */ 224 TargetGain=pInstance->Target>>(16-pInstance->Shift); // TargetGain in Q16.15 format 225 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]),TargetGain); 226 }else{ 227 /* Soft mixing has to be applied */ 228 HardMixing = FALSE; 229 if(pInstance->Shift!=0){ 230 Shift_Sat_v16xv16 ((LVM_INT16)pInstance->Shift,src,dst,n); 231 LVC_Core_MixSoft_1St_D16C31_WRA( &(ptrInstance->MixerStream[0]), dst, dst, n); 232 } 233 else 234 LVC_Core_MixSoft_1St_D16C31_WRA( &(ptrInstance->MixerStream[0]), src, dst, n); 235 } 236 } 237 238 /****************************************************************************** 239 HARD MIXING 240 *******************************************************************************/ 241 242 if (HardMixing){ 243 if (pInstance->Target == 0) 244 LoadConst_16(0, dst, n); 245 else if(pInstance->Shift!=0){ 246 Shift_Sat_v16xv16 ((LVM_INT16)pInstance->Shift,src,dst,n); 247 if ((pInstance->Target>>16) != 0x7FFF) 248 Mult3s_16x16( dst, (LVM_INT16)(pInstance->Target>>16), dst, n ); 249 } 250 else { 251 if ((pInstance->Target>>16) != 0x7FFF) 252 Mult3s_16x16( src, (LVM_INT16)(pInstance->Target>>16), dst, n ); 253 else if(src!=dst) 254 Copy_16(src, dst, n); 255 } 256 257 } 258 259 /****************************************************************************** 260 CALL BACK 261 *******************************************************************************/ 262 263 if (ptrInstance->MixerStream[0].CallbackSet){ 264 if (Abs_32(pInstance->Current-pInstance->Target) < pInstance->Delta){ 265 pInstance->Current = pInstance->Target; /* Difference is not significant anymore. Make them equal. */ 266 TargetGain=pInstance->Target>>(16-pInstance->Shift); // TargetGain in Q16.15 format 267 LVC_Mixer_SetTarget(ptrInstance->MixerStream,TargetGain); 268 ptrInstance->MixerStream[0].CallbackSet = FALSE; 269 if (ptrInstance->MixerStream[0].pCallBack != 0){ 270 (*ptrInstance->MixerStream[0].pCallBack) ( ptrInstance->MixerStream[0].pCallbackHandle, ptrInstance->MixerStream[0].pGeneralPurpose,ptrInstance->MixerStream[0].CallbackParam ); 271 } 272 } 273 } 274 } 275 #endif/*BUILD_FLOAT*/ 276 /**********************************************************************************/ 277