• 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 #include <audio_utils/BiquadFilter.h>
24 
25 #include <string.h>  // memset
26 #include "LVDBE.h"
27 #include "LVDBE_Private.h"
28 #include "VectorArithmetic.h"
29 #include "AGC.h"
30 #include "LVDBE_Coeffs.h" /* Filter coefficients */
31 #include <log/log.h>
32 
33 /********************************************************************************************/
34 /*                                                                                          */
35 /* FUNCTION:                 LVDBE_Process                                                  */
36 /*                                                                                          */
37 /* DESCRIPTION:                                                                             */
38 /*  Process function for the Bass Enhancement module.                                       */
39 /*                                                                                          */
40 /*  Data can be processed in two formats, stereo or mono-in-stereo. Data in mono            */
41 /*  format is not supported, the calling routine must convert the mono stream to            */
42 /*  mono-in-stereo.                                                                         */
43 /*                                                        ___________                       */
44 /*       ________                                        |           |    ________          */
45 /*      |        |    _____   |------------------------->|           |   |        |         */
46 /*      | 16-bit |   |     |  |    ________              |           |   | 32-bit |         */
47 /* -+-->|   to   |-->| HPF |--|   |        |    _____    | AGC Mixer |-->|   to   |--|      */
48 /*  |   | 32-bit |   |_____|  |   | Stereo |   |     |   |           |   | 16-bit |  |      */
49 /*  |   |________|            |-->|   to   |-->| BPF |-->|           |   |________|  0      */
50 /*  |                             |  Mono  |   |_____|   |___________|                \-->  */
51 /*  |                             |________|                                                */
52 /*  |                                                     _________                  0      */
53 /*  |                                                    |         |                 |      */
54 /*  |----------------------------------------------------| Volume  |-----------------|      */
55 /*                                                       | Control |                        */
56 /*                                                       |_________|                        */
57 /*                                                                                          */
58 /* PARAMETERS:                                                                              */
59 /*  hInstance                 Instance handle                                               */
60 /*  pInData                  Pointer to the input data                                      */
61 /*  pOutData                 Pointer to the output data                                     */
62 /*  NumSamples                 Number of samples in the input buffer                        */
63 /*                                                                                          */
64 /* RETURNS:                                                                                 */
65 /*  LVDBE_SUCCESS            Succeeded                                                      */
66 /*    LVDBE_TOOMANYSAMPLES    NumSamples was larger than the maximum block size             */
67 /*                                                                                          */
68 /* NOTES:                                                                                   */
69 /*  1. The input and output data must be 32-bit format. The input is scaled by a shift      */
70 /*     when converting from 16-bit format, this scaling allows for internal headroom in the */
71 /*     bass enhancement algorithm.                                                          */
72 /*  2. For a 16-bit implementation the converstion to 32-bit is removed and replaced with   */
73 /*     the headroom loss. This headroom loss is compensated in the volume control so the    */
74 /*     overall end to end gain is odB.                                                      */
75 /*                                                                                          */
76 /********************************************************************************************/
LVDBE_Process(LVDBE_Handle_t hInstance,const LVM_FLOAT * pInData,LVM_FLOAT * pOutData,const LVM_UINT16 NrFrames)77 LVDBE_ReturnStatus_en LVDBE_Process(
78         LVDBE_Handle_t hInstance, const LVM_FLOAT* pInData, LVM_FLOAT* pOutData,
79         const LVM_UINT16 NrFrames)  // updated to use samples = frames * channels.
80 {
81     LVDBE_Instance_t* pInstance = (LVDBE_Instance_t*)hInstance;
82     const LVM_INT32 NrChannels = pInstance->Params.NrChannels;
83     const LVM_INT32 NrSamples = NrChannels * NrFrames;
84 
85     /* Space to store DBE path computation */
86     LVM_FLOAT* const pScratch = (LVM_FLOAT*)pInstance->pScratch;
87 
88     /*
89      * Scratch for Mono path starts at offset of
90      * NrSamples float values from pScratch.
91      */
92     LVM_FLOAT* const pMono = pScratch + NrSamples;
93 
94     /*
95      * TRICKY: pMono is used and discarded by the DBE path.
96      *         so it is available for use for the pScratchVol
97      *         path which is computed afterwards.
98      *
99      * Space to store Volume Control path computation.
100      * This is identical to pMono (see TRICKY comment).
101      */
102     LVM_FLOAT* const pScratchVol = pMono;
103 
104     /*
105      * Check the number of frames is not too large
106      */
107     if (NrFrames > pInstance->Capabilities.MaxBlockSize) {
108         return LVDBE_TOOMANYSAMPLES;
109     }
110 
111     /*
112      * Check if the algorithm is enabled
113      */
114     /* DBE path is processed when DBE is ON or during On/Off transitions */
115     if ((pInstance->Params.OperatingMode == LVDBE_ON) ||
116         (LVC_Mixer_GetCurrent(&pInstance->pData->BypassMixer.MixerStream[0]) !=
117          LVC_Mixer_GetTarget(&pInstance->pData->BypassMixer.MixerStream[0]))) {
118         // make copy of input data
119         Copy_Float(pInData, pScratch, (LVM_INT16)NrSamples);
120 
121         /*
122          * Apply the high pass filter if selected
123          */
124         if (pInstance->Params.HPFSelect == LVDBE_HPF_ON) {
125             pInstance->pHPFBiquad->process(pScratch, pScratch, NrFrames);
126         }
127 
128         /*
129          * Create the mono stream
130          */
131         FromMcToMono_Float(pScratch,            /* Source */
132                            pMono,               /* Mono destination */
133                            (LVM_INT16)NrFrames, /* Number of frames */
134                            (LVM_INT16)NrChannels);
135 
136         /*
137          * Apply the band pass filter
138          */
139         pInstance->pBPFBiquad->process(pMono, pMono, NrFrames);
140 
141         /*
142          * Apply the AGC and mix
143          */
144         AGC_MIX_VOL_Mc1Mon_D32_WRA(&pInstance->pData->AGCInstance, /* Instance pointer      */
145                                    pScratch,                       /* Source         */
146                                    pMono,                          /* Mono band pass source */
147                                    pScratch,                       /* Destination    */
148                                    NrFrames,                       /* Number of frames     */
149                                    NrChannels);                    /* Number of channels     */
150     } else {
151         // clear DBE processed path
152         memset(pScratch, 0, sizeof(*pScratch) * NrSamples);
153     }
154 
155     /* Bypass Volume path is processed when DBE is OFF or during On/Off transitions */
156     if ((pInstance->Params.OperatingMode == LVDBE_OFF) ||
157         (LVC_Mixer_GetCurrent(&pInstance->pData->BypassMixer.MixerStream[1]) !=
158          LVC_Mixer_GetTarget(&pInstance->pData->BypassMixer.MixerStream[1]))) {
159         /*
160          * The algorithm is disabled but volume management is required to compensate for
161          * headroom and volume (if enabled)
162          */
163         LVC_MixSoft_Mc_D16C31_SAT(&pInstance->pData->BypassVolume, pInData, pScratchVol,
164                                   (LVM_INT16)NrFrames, (LVM_INT16)NrChannels);
165     } else {
166         // clear bypass volume path
167         memset(pScratchVol, 0, sizeof(*pScratchVol) * NrSamples);
168     }
169 
170     /*
171      * Mix DBE processed path and bypass volume path
172      */
173     LVC_MixSoft_2Mc_D16C31_SAT(&pInstance->pData->BypassMixer, pScratch, pScratchVol, pOutData,
174                                (LVM_INT16)NrFrames, (LVM_INT16)NrChannels);
175     return LVDBE_SUCCESS;
176 }
177