LVEQNB_Process.c revision b302bd5d288be2d3363b80053ca2392560b00b25
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/*                                                                                      */
20/*  Includes                                                                            */
21/*                                                                                      */
22/****************************************************************************************/
23
24#include "LVEQNB.h"
25#include "LVEQNB_Private.h"
26#include "VectorArithmetic.h"
27#include "BIQUAD.h"
28
29
30/****************************************************************************************/
31/*                                                                                      */
32/*  Defines                                                                             */
33/*                                                                                      */
34/****************************************************************************************/
35
36#define SHIFT       13
37
38/****************************************************************************************/
39/*                                                                                      */
40/* FUNCTION:                LVEQNB_Process                                              */
41/*                                                                                      */
42/* DESCRIPTION:                                                                         */
43/*  Process function for the N-Band Equaliser module.                                   */
44/*                                                                                      */
45/* PARAMETERS:                                                                          */
46/*  hInstance               Instance handle                                             */
47/*  pInData                 Pointer to the input data                                   */
48/*  pOutData                Pointer to the output data                                  */
49/*  NumSamples              Number of samples in the input buffer                       */
50/*                                                                                      */
51/* RETURNS:                                                                             */
52/*  LVEQNB_SUCCESS          Succeeded                                                   */
53/*  LVEQNB_NULLADDRESS      When hInstance, pInData or pOutData are NULL                */
54/*  LVEQNB_ALIGNMENTERROR   When pInData or pOutData are not 32-bit aligned             */
55/*  LVEQNB_TOOMANYSAMPLES   NumSamples was larger than the maximum block size           */
56/*                                                                                      */
57/* NOTES:                                                                               */
58/*                                                                                      */
59/****************************************************************************************/
60
61LVEQNB_ReturnStatus_en LVEQNB_Process(LVEQNB_Handle_t       hInstance,
62                                      const LVM_INT16       *pInData,
63                                      LVM_INT16             *pOutData,
64                                      LVM_UINT16            NumSamples)
65{
66
67    LVM_UINT16          i;
68    Biquad_Instance_t   *pBiquad;
69    LVEQNB_Instance_t   *pInstance = (LVEQNB_Instance_t  *)hInstance;
70    LVM_INT32           *pScratch;
71
72
73     /* Check for NULL pointers */
74    if((hInstance == LVM_NULL) || (pInData == LVM_NULL) || (pOutData == LVM_NULL))
75    {
76        return LVEQNB_NULLADDRESS;
77    }
78
79    /* Check if the input and output data buffers are 32-bit aligned */
80    if ((((uintptr_t)pInData % 4) != 0) || (((uintptr_t)pOutData % 4) != 0))
81    {
82        return LVEQNB_ALIGNMENTERROR;
83    }
84
85    pScratch  = (LVM_INT32 *)pInstance->pFastTemporary;
86
87    /*
88    * Check the number of samples is not too large
89    */
90    if (NumSamples > pInstance->Capabilities.MaxBlockSize)
91    {
92        return(LVEQNB_TOOMANYSAMPLES);
93    }
94
95    if (pInstance->Params.OperatingMode == LVEQNB_ON)
96    {
97        /*
98         * Convert from 16-bit to 32-bit
99         */
100        Int16LShiftToInt32_16x32((LVM_INT16 *)pInData,      /* Source */
101                                 pScratch,                  /* Destination */
102                                 (LVM_INT16)(2*NumSamples), /* Left and Right */
103                                 SHIFT);                    /* Scaling shift */
104
105        /*
106         * For each section execte the filter unless the gain is 0dB
107         */
108        if (pInstance->NBands != 0)
109        {
110            for (i=0; i<pInstance->NBands; i++)
111            {
112                /*
113                 * Check if band is non-zero dB gain
114                 */
115                if (pInstance->pBandDefinitions[i].Gain != 0)
116                {
117                    /*
118                     * Get the address of the biquad instance
119                     */
120                    pBiquad = &pInstance->pEQNB_FilterState[i];
121
122
123                    /*
124                     * Select single or double precision as required
125                     */
126                    switch (pInstance->pBiquadType[i])
127                    {
128                        case LVEQNB_SinglePrecision:
129                        {
130                            PK_2I_D32F32C14G11_TRC_WRA_01(pBiquad,
131                                                          (LVM_INT32 *)pScratch,
132                                                          (LVM_INT32 *)pScratch,
133                                                          (LVM_INT16)NumSamples);
134                            break;
135                        }
136
137                        case LVEQNB_DoublePrecision:
138                        {
139                            PK_2I_D32F32C30G11_TRC_WRA_01(pBiquad,
140                                                          (LVM_INT32 *)pScratch,
141                                                          (LVM_INT32 *)pScratch,
142                                                          (LVM_INT16)NumSamples);
143                            break;
144                        }
145                        default:
146                            break;
147                    }
148                }
149            }
150        }
151
152
153        if(pInstance->bInOperatingModeTransition == LVM_TRUE){
154                /*
155                 * Convert from 32-bit to 16- bit and saturate
156                 */
157                Int32RShiftToInt16_Sat_32x16(pScratch,                      /* Source */
158                                             (LVM_INT16 *)pScratch,         /* Destination */
159                                             (LVM_INT16)(2*NumSamples),     /* Left and Right */
160                                             SHIFT);                        /* Scaling shift */
161
162                LVC_MixSoft_2St_D16C31_SAT(&pInstance->BypassMixer,
163                                                (LVM_INT16 *)pScratch,
164                                                (LVM_INT16 *)pInData,
165                                                (LVM_INT16 *)pScratch,
166                                                (LVM_INT16)(2*NumSamples));
167
168                Copy_16((LVM_INT16*)pScratch,                           /* Source */
169                        pOutData,                                       /* Destination */
170                        (LVM_INT16)(2*NumSamples));                     /* Left and Right samples */
171        }
172        else{
173
174            /*
175             * Convert from 32-bit to 16- bit and saturate
176             */
177            Int32RShiftToInt16_Sat_32x16(pScratch,              /* Source */
178                                         pOutData,              /* Destination */
179                                         (LVM_INT16 )(2*NumSamples), /* Left and Right */
180                                         SHIFT);                /* Scaling shift */
181        }
182    }
183    else
184    {
185        /*
186         * Mode is OFF so copy the data if necessary
187         */
188        if (pInData != pOutData)
189        {
190            Copy_16(pInData,                                    /* Source */
191                    pOutData,                                   /* Destination */
192                    (LVM_INT16)(2*NumSamples));                 /* Left and Right samples */
193        }
194    }
195
196
197
198    return(LVEQNB_SUCCESS);
199
200}
201