Home | History | Annotate | Download | only in src
      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