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 MIXINSOFT_D16C31_SAT 35 ***********************************************************************************/ 36 #ifdef BUILD_FLOAT 37 void LVC_MixInSoft_D16C31_SAT( LVMixer3_1St_FLOAT_st *ptrInstance, 38 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_MixInSoft_D16C31_SAT(&(ptrInstance->MixerStream[0]), src, dst, n); 67 } 68 } 69 70 /****************************************************************************** 71 HARD MIXING 72 *******************************************************************************/ 73 74 if (HardMixing){ 75 if (pInstance->Target != 0){ /* Nothing to do in case Target = 0 */ 76 if ((pInstance->Target) == 1.0f){ 77 Add2_Sat_Float(src, dst, n); 78 } 79 else{ 80 Mac3s_Sat_Float(src, (pInstance->Target), dst, n); 81 /* In case the LVCore function would have changed the Current value */ 82 pInstance->Current = pInstance->Target; 83 } 84 } 85 } 86 87 88 /****************************************************************************** 89 CALL BACK 90 *******************************************************************************/ 91 92 if (ptrInstance->MixerStream[0].CallbackSet){ 93 if (Abs_Float(pInstance->Current - pInstance->Target) < pInstance->Delta){ 94 pInstance->Current = pInstance->Target; /* Difference is not significant anymore. \ 95 Make them equal. */ 96 TargetGain = pInstance->Target; 97 LVC_Mixer_SetTarget(ptrInstance->MixerStream, TargetGain); 98 ptrInstance->MixerStream[0].CallbackSet = FALSE; 99 if (ptrInstance->MixerStream[0].pCallBack != 0){ 100 (*ptrInstance->MixerStream[0].pCallBack) ( \ 101 ptrInstance->MixerStream[0].pCallbackHandle, 102 ptrInstance->MixerStream[0].pGeneralPurpose, 103 ptrInstance->MixerStream[0].CallbackParam ); 104 } 105 } 106 } 107 108 } 109 #else 110 void LVC_MixInSoft_D16C31_SAT( LVMixer3_1St_st *ptrInstance, 111 LVM_INT16 *src, 112 LVM_INT16 *dst, 113 LVM_INT16 n) 114 { 115 char HardMixing = TRUE; 116 LVM_INT32 TargetGain; 117 Mix_Private_st *pInstance=(Mix_Private_st *)(ptrInstance->MixerStream[0].PrivateParams); 118 119 if(n<=0) return; 120 121 /****************************************************************************** 122 SOFT MIXING 123 *******************************************************************************/ 124 if (pInstance->Current != pInstance->Target) 125 { 126 if(pInstance->Delta == 0x7FFFFFFF){ 127 pInstance->Current = pInstance->Target; 128 TargetGain=pInstance->Target>>(16-pInstance->Shift); // TargetGain in Q16.15 format 129 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]),TargetGain); 130 }else if (Abs_32(pInstance->Current-pInstance->Target) < pInstance->Delta){ 131 pInstance->Current = pInstance->Target; /* Difference is not significant anymore. Make them equal. */ 132 TargetGain=pInstance->Target>>(16-pInstance->Shift); // TargetGain in Q16.15 format 133 LVC_Mixer_SetTarget(&(ptrInstance->MixerStream[0]),TargetGain); 134 }else{ 135 /* Soft mixing has to be applied */ 136 HardMixing = FALSE; 137 if(pInstance->Shift!=0){ 138 Shift_Sat_v16xv16 ((LVM_INT16)pInstance->Shift,src,src,n); 139 LVC_Core_MixInSoft_D16C31_SAT( &(ptrInstance->MixerStream[0]), src, dst, n); 140 } 141 else 142 LVC_Core_MixInSoft_D16C31_SAT( &(ptrInstance->MixerStream[0]), src, dst, n); 143 } 144 } 145 146 /****************************************************************************** 147 HARD MIXING 148 *******************************************************************************/ 149 150 if (HardMixing){ 151 if (pInstance->Target != 0){ /* Nothing to do in case Target = 0 */ 152 if ((pInstance->Target>>16) == 0x7FFF){ 153 if(pInstance->Shift!=0) 154 Shift_Sat_v16xv16 ((LVM_INT16)pInstance->Shift,src,src,n); 155 Add2_Sat_16x16( src, dst, n ); 156 } 157 else{ 158 if(pInstance->Shift!=0) 159 Shift_Sat_v16xv16 ((LVM_INT16)pInstance->Shift,src,src,n); 160 Mac3s_Sat_16x16(src,(LVM_INT16)(pInstance->Target>>16),dst,n); 161 pInstance->Current = pInstance->Target; /* In case the LVCore function would have changed the Current value */ 162 } 163 } 164 } 165 166 167 /****************************************************************************** 168 CALL BACK 169 *******************************************************************************/ 170 171 if (ptrInstance->MixerStream[0].CallbackSet){ 172 if (Abs_32(pInstance->Current-pInstance->Target) < pInstance->Delta){ 173 pInstance->Current = pInstance->Target; /* Difference is not significant anymore. Make them equal. */ 174 TargetGain=pInstance->Target>>(16-pInstance->Shift); // TargetGain in Q16.15 format 175 LVC_Mixer_SetTarget(ptrInstance->MixerStream,TargetGain); 176 ptrInstance->MixerStream[0].CallbackSet = FALSE; 177 if (ptrInstance->MixerStream[0].pCallBack != 0){ 178 (*ptrInstance->MixerStream[0].pCallBack) ( ptrInstance->MixerStream[0].pCallbackHandle, ptrInstance->MixerStream[0].pGeneralPurpose,ptrInstance->MixerStream[0].CallbackParam ); 179 } 180 } 181 } 182 183 } 184 #endif 185 /**********************************************************************************/ 186