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 LVC_MixSoft_1St_2i_D16C31_SAT
     35 ***********************************************************************************/
     36 #ifdef BUILD_FLOAT
     37 void 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
    168 void 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