summaryrefslogtreecommitdiffstats
path: root/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.c
blob: 58f58ed683157311f8ef25f19dfd40aa8fd5e817 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/*
 * Copyright (C) 2004-2010 NXP Software
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/****************************************************************************************/
/*                                                                                      */
/*  Includes                                                                            */
/*                                                                                      */
/****************************************************************************************/

#include "LVEQNB.h"
#include "LVEQNB_Private.h"
#include "VectorArithmetic.h"
#include "BIQUAD.h"


/****************************************************************************************/
/*                                                                                      */
/*  Defines                                                                             */
/*                                                                                      */
/****************************************************************************************/

#define SHIFT       13

/****************************************************************************************/
/*                                                                                      */
/* FUNCTION:                LVEQNB_Process                                              */
/*                                                                                      */
/* DESCRIPTION:                                                                         */
/*  Process function for the N-Band Equaliser module.                                   */
/*                                                                                      */
/* PARAMETERS:                                                                          */
/*  hInstance               Instance handle                                             */
/*  pInData                 Pointer to the input data                                   */
/*  pOutData                Pointer to the output data                                  */
/*  NumSamples              Number of samples in the input buffer                       */
/*                                                                                      */
/* RETURNS:                                                                             */
/*  LVEQNB_SUCCESS          Succeeded                                                   */
/*  LVEQNB_NULLADDRESS      When hInstance, pInData or pOutData are NULL                */
/*  LVEQNB_ALIGNMENTERROR   When pInData or pOutData are not 32-bit aligned             */
/*  LVEQNB_TOOMANYSAMPLES   NumSamples was larger than the maximum block size           */
/*                                                                                      */
/* NOTES:                                                                               */
/*                                                                                      */
/****************************************************************************************/

LVEQNB_ReturnStatus_en LVEQNB_Process(LVEQNB_Handle_t       hInstance,
                                      const LVM_INT16       *pInData,
                                      LVM_INT16             *pOutData,
                                      LVM_UINT16            NumSamples)
{

    LVM_UINT16          i;
    Biquad_Instance_t   *pBiquad;
    LVEQNB_Instance_t   *pInstance = (LVEQNB_Instance_t  *)hInstance;
    LVM_INT32           *pScratch;


     /* Check for NULL pointers */
    if((hInstance == LVM_NULL) || (pInData == LVM_NULL) || (pOutData == LVM_NULL))
    {
        return LVEQNB_NULLADDRESS;
    }

    /* Check if the input and output data buffers are 32-bit aligned */
    if ((((uintptr_t)pInData % 4) != 0) || (((uintptr_t)pOutData % 4) != 0))
    {
        return LVEQNB_ALIGNMENTERROR;
    }

    pScratch  = (LVM_INT32 *)pInstance->pFastTemporary;

    /*
    * Check the number of samples is not too large
    */
    if (NumSamples > pInstance->Capabilities.MaxBlockSize)
    {
        return(LVEQNB_TOOMANYSAMPLES);
    }

    if (pInstance->Params.OperatingMode == LVEQNB_ON)
    {
        /*
         * Convert from 16-bit to 32-bit
         */
        Int16LShiftToInt32_16x32((LVM_INT16 *)pInData,      /* Source */
                                 pScratch,                  /* Destination */
                                 (LVM_INT16)(2*NumSamples), /* Left and Right */
                                 SHIFT);                    /* Scaling shift */

        /*
         * For each section execte the filter unless the gain is 0dB
         */
        if (pInstance->NBands != 0)
        {
            for (i=0; i<pInstance->NBands; i++)
            {
                /*
                 * Check if band is non-zero dB gain
                 */
                if (pInstance->pBandDefinitions[i].Gain != 0)
                {
                    /*
                     * Get the address of the biquad instance
                     */
                    pBiquad = &pInstance->pEQNB_FilterState[i];


                    /*
                     * Select single or double precision as required
                     */
                    switch (pInstance->pBiquadType[i])
                    {
                        case LVEQNB_SinglePrecision:
                        {
                            PK_2I_D32F32C14G11_TRC_WRA_01(pBiquad,
                                                          (LVM_INT32 *)pScratch,
                                                          (LVM_INT32 *)pScratch,
                                                          (LVM_INT16)NumSamples);
                            break;
                        }

                        case LVEQNB_DoublePrecision:
                        {
                            PK_2I_D32F32C30G11_TRC_WRA_01(pBiquad,
                                                          (LVM_INT32 *)pScratch,
                                                          (LVM_INT32 *)pScratch,
                                                          (LVM_INT16)NumSamples);
                            break;
                        }
                        default:
                            break;
                    }
                }
            }
        }


        if(pInstance->bInOperatingModeTransition == LVM_TRUE){
                /*
                 * Convert from 32-bit to 16- bit and saturate
                 */
                Int32RShiftToInt16_Sat_32x16(pScratch,                      /* Source */
                                             (LVM_INT16 *)pScratch,         /* Destination */
                                             (LVM_INT16)(2*NumSamples),     /* Left and Right */
                                             SHIFT);                        /* Scaling shift */

                LVC_MixSoft_2St_D16C31_SAT(&pInstance->BypassMixer,
                                                (LVM_INT16 *)pScratch,
                                                (LVM_INT16 *)pInData,
                                                (LVM_INT16 *)pScratch,
                                                (LVM_INT16)(2*NumSamples));

                Copy_16((LVM_INT16*)pScratch,                           /* Source */
                        pOutData,                                       /* Destination */
                        (LVM_INT16)(2*NumSamples));                     /* Left and Right samples */
        }
        else{

            /*
             * Convert from 32-bit to 16- bit and saturate
             */
            Int32RShiftToInt16_Sat_32x16(pScratch,              /* Source */
                                         pOutData,              /* Destination */
                                         (LVM_INT16 )(2*NumSamples), /* Left and Right */
                                         SHIFT);                /* Scaling shift */
        }
    }
    else
    {
        /*
         * Mode is OFF so copy the data if necessary
         */
        if (pInData != pOutData)
        {
            Copy_16(pInData,                                    /* Source */
                    pOutData,                                   /* Destination */
                    (LVM_INT16)(2*NumSamples));                 /* Left and Right samples */
        }
    }



    return(LVEQNB_SUCCESS);

}