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 "ScalarArithmetic.h"
24#include "LVM_Macros.h"
25
26/**********************************************************************************
27   FUNCTION LVC_Core_MixSoft_1St_2i_D16C31_WRA
28***********************************************************************************/
29
30void LVC_Core_MixSoft_1St_2i_D16C31_WRA( LVMixer3_st        *ptrInstance1,
31                                         LVMixer3_st        *ptrInstance2,
32                                         const LVM_INT16    *src,
33                                         LVM_INT16          *dst,
34                                         LVM_INT16          n)
35{
36    LVM_INT16   OutLoop;
37    LVM_INT16   InLoop;
38    LVM_INT16   CurrentShortL;
39    LVM_INT16   CurrentShortR;
40    LVM_INT32   ii;
41    Mix_Private_st  *pInstanceL=(Mix_Private_st *)(ptrInstance1->PrivateParams);
42    Mix_Private_st  *pInstanceR=(Mix_Private_st *)(ptrInstance2->PrivateParams);
43
44    LVM_INT32   DeltaL=pInstanceL->Delta;
45    LVM_INT32   CurrentL=pInstanceL->Current;
46    LVM_INT32   TargetL=pInstanceL->Target;
47
48    LVM_INT32   DeltaR=pInstanceR->Delta;
49    LVM_INT32   CurrentR=pInstanceR->Current;
50    LVM_INT32   TargetR=pInstanceR->Target;
51
52    LVM_INT32   Temp;
53
54    InLoop = (LVM_INT16)(n >> 2); /* Process per 4 samples */
55    OutLoop = (LVM_INT16)(n - (InLoop << 2));
56
57    if (OutLoop)
58    {
59        if(CurrentL<TargetL)
60        {
61            ADD2_SAT_32x32(CurrentL,DeltaL,Temp);                                      /* Q31 + Q31 into Q31*/
62            CurrentL=Temp;
63            if (CurrentL > TargetL)
64                CurrentL = TargetL;
65        }
66        else
67        {
68            CurrentL -= DeltaL;                                                        /* Q31 + Q31 into Q31*/
69            if (CurrentL < TargetL)
70                CurrentL = TargetL;
71        }
72
73        if(CurrentR<TargetR)
74        {
75            ADD2_SAT_32x32(CurrentR,DeltaR,Temp);                                      /* Q31 + Q31 into Q31*/
76            CurrentR=Temp;
77            if (CurrentR > TargetR)
78                CurrentR = TargetR;
79        }
80        else
81        {
82            CurrentR -= DeltaR;                                                        /* Q31 + Q31 into Q31*/
83            if (CurrentR < TargetR)
84                CurrentR = TargetR;
85        }
86
87        CurrentShortL = (LVM_INT16)(CurrentL>>16);                                 /* From Q31 to Q15*/
88        CurrentShortR = (LVM_INT16)(CurrentR>>16);                                 /* From Q31 to Q15*/
89
90        for (ii = OutLoop*2; ii != 0; ii-=2)
91        {
92            *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShortL)>>15);    /* Q15*Q15>>15 into Q15 */
93            *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShortR)>>15);    /* Q15*Q15>>15 into Q15 */
94        }
95    }
96
97    for (ii = InLoop*2; ii != 0; ii-=2)
98    {
99        if(CurrentL<TargetL)
100        {
101            ADD2_SAT_32x32(CurrentL,DeltaL,Temp);                                      /* Q31 + Q31 into Q31*/
102            CurrentL=Temp;
103            if (CurrentL > TargetL)
104                CurrentL = TargetL;
105        }
106        else
107        {
108            CurrentL -= DeltaL;                                                        /* Q31 + Q31 into Q31*/
109            if (CurrentL < TargetL)
110                CurrentL = TargetL;
111        }
112
113        if(CurrentR<TargetR)
114        {
115            ADD2_SAT_32x32(CurrentR,DeltaR,Temp);                                      /* Q31 + Q31 into Q31*/
116            CurrentR=Temp;
117            if (CurrentR > TargetR)
118                CurrentR = TargetR;
119        }
120        else
121        {
122            CurrentR -= DeltaR;                                                        /* Q31 + Q31 into Q31*/
123            if (CurrentR < TargetR)
124                CurrentR = TargetR;
125        }
126
127        CurrentShortL = (LVM_INT16)(CurrentL>>16);                                 /* From Q31 to Q15*/
128        CurrentShortR = (LVM_INT16)(CurrentR>>16);                                 /* From Q31 to Q15*/
129
130        *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShortL)>>15);    /* Q15*Q15>>15 into Q15 */
131        *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShortR)>>15);    /* Q15*Q15>>15 into Q15 */
132        *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShortL)>>15);
133        *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShortR)>>15);
134        *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShortL)>>15);
135        *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShortR)>>15);
136        *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShortL)>>15);
137        *(dst++) = (LVM_INT16)(((LVM_INT32)*(src++) * (LVM_INT32)CurrentShortR)>>15);
138    }
139    pInstanceL->Current=CurrentL;
140    pInstanceR->Current=CurrentR;
141
142}
143/**********************************************************************************/
144