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 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