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