• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <log/log.h>
30 
31 /****************************************************************************************/
32 /*                                                                                      */
33 /*  Defines                                                                             */
34 /*                                                                                      */
35 /****************************************************************************************/
36 
37 #define SHIFT 13
38 
39 /****************************************************************************************/
40 /*                                                                                      */
41 /* FUNCTION:                LVEQNB_Process                                              */
42 /*                                                                                      */
43 /* DESCRIPTION:                                                                         */
44 /*  Process function for the N-Band Equaliser module.                                   */
45 /*                                                                                      */
46 /* PARAMETERS:                                                                          */
47 /*  hInstance               Instance handle                                             */
48 /*  pInData                 Pointer to the input data                                   */
49 /*  pOutData                Pointer to the output data                                  */
50 /*  NumSamples              Number of samples in the input buffer                       */
51 /*                                                                                      */
52 /* RETURNS:                                                                             */
53 /*  LVEQNB_SUCCESS          Succeeded                                                   */
54 /*  LVEQNB_NULLADDRESS      When hInstance, pInData or pOutData are NULL                */
55 /*  LVEQNB_ALIGNMENTERROR   When pInData or pOutData are not 32-bit aligned             */
56 /*  LVEQNB_TOOMANYSAMPLES   NumSamples was larger than the maximum block size           */
57 /*                                                                                      */
58 /* NOTES:                                                                               */
59 /*                                                                                      */
60 /****************************************************************************************/
LVEQNB_Process(LVEQNB_Handle_t hInstance,const LVM_FLOAT * pInData,LVM_FLOAT * pOutData,const LVM_UINT16 NrFrames)61 LVEQNB_ReturnStatus_en LVEQNB_Process(
62         LVEQNB_Handle_t hInstance, const LVM_FLOAT* pInData, LVM_FLOAT* pOutData,
63         const LVM_UINT16 NrFrames) {  // updated to use samples = frames * channels.
64     LVEQNB_Instance_t* pInstance = (LVEQNB_Instance_t*)hInstance;
65     const LVM_INT32 NrChannels = pInstance->Params.NrChannels;
66     const LVM_INT32 NrSamples = NrChannels * NrFrames;
67 
68     /* Check for NULL pointers */
69     if ((hInstance == LVM_NULL) || (pInData == LVM_NULL) || (pOutData == LVM_NULL)) {
70         return LVEQNB_NULLADDRESS;
71     }
72 
73     /* Check if the input and output data buffers are 32-bit aligned */
74     if ((((uintptr_t)pInData % 4) != 0) || (((uintptr_t)pOutData % 4) != 0)) {
75         return LVEQNB_ALIGNMENTERROR;
76     }
77 
78     LVM_FLOAT* const pScratch = (LVM_FLOAT*)pInstance->pFastTemporary;
79 
80     /*
81      * Check the number of frames is not too large
82      */
83     if (NrFrames > pInstance->Capabilities.MaxBlockSize) {
84         return LVEQNB_TOOMANYSAMPLES;
85     }
86 
87     if (pInstance->Params.OperatingMode == LVEQNB_ON) {
88         /*
89          * Copy input data in to scratch buffer
90          */
91         Copy_Float(pInData,  /* Source */
92                    pScratch, /* Destination */
93                    (LVM_INT16)NrSamples);
94 
95         /*
96          * For each section execte the filter unless the gain is 0dB
97          */
98         if (pInstance->NBands != 0) {
99             for (LVM_UINT16 i = 0; i < pInstance->NBands; i++) {
100                 /*
101                  * Check if band is non-zero dB gain
102                  */
103                 if (pInstance->pBandDefinitions[i].Gain != 0) {
104                     /*
105                      * Select single or double precision as required
106                      */
107                     switch (pInstance->pBiquadType[i]) {
108                         case LVEQNB_SinglePrecision_Float: {
109                             LVM_FLOAT* pTemp = pScratch + NrSamples;
110                             pInstance->eqBiquad[i].process(pTemp, pScratch, NrFrames);
111                             const auto gain = pInstance->gain[i];
112                             for (unsigned j = 0; j < NrSamples; ++j) {
113                                 pScratch[j] += pTemp[j] * gain;
114                             }
115                             break;
116                         }
117                         default:
118                             break;
119                     }
120                 }
121             }
122         }
123 
124         if (pInstance->bInOperatingModeTransition == LVM_TRUE) {
125             LVC_MixSoft_2Mc_D16C31_SAT(&pInstance->BypassMixer, pScratch, pInData, pScratch,
126                                        (LVM_INT16)NrFrames, (LVM_INT16)NrChannels);
127             // duplicate with else clause(s)
128             Copy_Float(pScratch,              /* Source */
129                        pOutData,              /* Destination */
130                        (LVM_INT16)NrSamples); /* All channel samples */
131         } else {
132             Copy_Float(pScratch,              /* Source */
133                        pOutData,              /* Destination */
134                        (LVM_INT16)NrSamples); /* All channel samples */
135         }
136     } else {
137         /*
138          * Mode is OFF so copy the data if necessary
139          */
140         if (pInData != pOutData) {
141             Copy_Float(pInData,               /* Source */
142                        pOutData,              /* Destination */
143                        (LVM_INT16)NrSamples); /* All channel samples */
144         }
145     }
146     return LVEQNB_SUCCESS;
147 }
148