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