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 "LVDBE.h"
25 #include "LVDBE_Private.h"
26 #include "VectorArithmetic.h"
27 #include "AGC.h"
28 #include "LVDBE_Coeffs.h" /* Filter coefficients */
29
30
31 /********************************************************************************************/
32 /* */
33 /* FUNCTION: LVDBE_Process */
34 /* */
35 /* DESCRIPTION: */
36 /* Process function for the Bass Enhancement module. */
37 /* */
38 /* Data can be processed in two formats, stereo or mono-in-stereo. Data in mono */
39 /* format is not supported, the calling routine must convert the mono stream to */
40 /* mono-in-stereo. */
41 /* ___________ */
42 /* ________ | | ________ */
43 /* | | _____ |------------------------->| | | | */
44 /* | 16-bit | | | | ________ | | | 32-bit | */
45 /* -+-->| to |-->| HPF |--| | | _____ | AGC Mixer |-->| to |--| */
46 /* | | 32-bit | |_____| | | Stereo | | | | | | 16-bit | | */
47 /* | |________| |-->| to |-->| BPF |-->| | |________| 0 */
48 /* | | Mono | |_____| |___________| \--> */
49 /* | |________| */
50 /* | _________ 0 */
51 /* | | | | */
52 /* |----------------------------------------------------| Volume |-----------------| */
53 /* | Control | */
54 /* |_________| */
55 /* */
56 /* PARAMETERS: */
57 /* hInstance Instance handle */
58 /* pInData Pointer to the input data */
59 /* pOutData Pointer to the output data */
60 /* NumSamples Number of samples in the input buffer */
61 /* */
62 /* RETURNS: */
63 /* LVDBE_SUCCESS Succeeded */
64 /* LVDBE_TOOMANYSAMPLES NumSamples was larger than the maximum block size */
65 /* */
66 /* NOTES: */
67 /* 1. The input and output data must be 32-bit format. The input is scaled by a shift */
68 /* when converting from 16-bit format, this scaling allows for internal headroom in the */
69 /* bass enhancement algorithm. */
70 /* 2. For a 16-bit implementation the converstion to 32-bit is removed and replaced with */
71 /* the headroom loss. This headroom loss is compensated in the volume control so the */
72 /* overall end to end gain is odB. */
73 /* */
74 /********************************************************************************************/
75
LVDBE_Process(LVDBE_Handle_t hInstance,const LVM_INT16 * pInData,LVM_INT16 * pOutData,LVM_UINT16 NumSamples)76 LVDBE_ReturnStatus_en LVDBE_Process(LVDBE_Handle_t hInstance,
77 const LVM_INT16 *pInData,
78 LVM_INT16 *pOutData,
79 LVM_UINT16 NumSamples)
80 {
81
82 LVDBE_Instance_t *pInstance =(LVDBE_Instance_t *)hInstance;
83 LVM_INT32 *pScratch = (LVM_INT32 *)pInstance->MemoryTable.Region[LVDBE_MEMREGION_SCRATCH].pBaseAddress;
84 LVM_INT32 *pMono;
85 LVM_INT16 *pInput = (LVM_INT16 *)pInData;
86
87
88 /* Scratch for Volume Control starts at offset of 2*NumSamples short values from pScratch */
89 LVM_INT16 *pScratchVol = (LVM_INT16 *)(&pScratch[NumSamples]);
90
91 /* Scratch for Mono path starts at offset of 2*NumSamples 32-bit values from pScratch */
92 pMono = &pScratch[2*NumSamples];
93
94 /*
95 * Check the number of samples is not too large
96 */
97 if (NumSamples > pInstance->Capabilities.MaxBlockSize)
98 {
99 return(LVDBE_TOOMANYSAMPLES);
100 }
101
102 /*
103 * Check if the algorithm is enabled
104 */
105 /* DBE path is processed when DBE is ON or during On/Off transitions */
106 if ((pInstance->Params.OperatingMode == LVDBE_ON)||
107 (LVC_Mixer_GetCurrent(&pInstance->pData->BypassMixer.MixerStream[0])
108 !=LVC_Mixer_GetTarget(&pInstance->pData->BypassMixer.MixerStream[0])))
109 {
110
111 /*
112 * Convert 16-bit samples to 32-bit and scale
113 * (For a 16-bit implementation apply headroom loss here)
114 */
115 Int16LShiftToInt32_16x32(pInput, /* Source 16-bit data */
116 pScratch, /* Dest. 32-bit data */
117 (LVM_INT16)(2*NumSamples), /* Left and right */
118 LVDBE_SCALESHIFT); /* Shift scale */
119
120
121 /*
122 * Apply the high pass filter if selected
123 */
124 if (pInstance->Params.HPFSelect == LVDBE_HPF_ON)
125 {
126 BQ_2I_D32F32C30_TRC_WRA_01(&pInstance->pCoef->HPFInstance,/* Filter instance */
127 (LVM_INT32 *)pScratch, /* Source */
128 (LVM_INT32 *)pScratch, /* Destination */
129 (LVM_INT16)NumSamples); /* Number of samples */
130 }
131
132
133 /*
134 * Create the mono stream
135 */
136 From2iToMono_32(pScratch, /* Stereo source */
137 pMono, /* Mono destination */
138 (LVM_INT16)NumSamples); /* Number of samples */
139
140
141 /*
142 * Apply the band pass filter
143 */
144 BP_1I_D32F32C30_TRC_WRA_02(&pInstance->pCoef->BPFInstance, /* Filter instance */
145 (LVM_INT32 *)pMono, /* Source */
146 (LVM_INT32 *)pMono, /* Destination */
147 (LVM_INT16)NumSamples); /* Number of samples */
148
149
150 /*
151 * Apply the AGC and mix
152 */
153 AGC_MIX_VOL_2St1Mon_D32_WRA(&pInstance->pData->AGCInstance, /* Instance pointer */
154 pScratch, /* Stereo source */
155 pMono, /* Mono band pass source */
156 pScratch, /* Stereo destination */
157 NumSamples); /* Number of samples */
158
159 /*
160 * Convert 32-bit samples to 16-bit and saturate
161 * (Not required for 16-bit implemenations)
162 */
163 Int32RShiftToInt16_Sat_32x16(pScratch, /* Source 32-bit data */
164 (LVM_INT16 *)pScratch, /* Dest. 16-bit data */
165 (LVM_INT16)(2*NumSamples), /* Left and right */
166 LVDBE_SCALESHIFT); /* Shift scale */
167
168 }
169
170 /* Bypass Volume path is processed when DBE is OFF or during On/Off transitions */
171 if ((pInstance->Params.OperatingMode == LVDBE_OFF)||
172 (LVC_Mixer_GetCurrent(&pInstance->pData->BypassMixer.MixerStream[1])
173 !=LVC_Mixer_GetTarget(&pInstance->pData->BypassMixer.MixerStream[1])))
174 {
175
176 /*
177 * The algorithm is disabled but volume management is required to compensate for
178 * headroom and volume (if enabled)
179 */
180 LVC_MixSoft_1St_D16C31_SAT(&pInstance->pData->BypassVolume,
181 pInData,
182 pScratchVol,
183 (LVM_INT16)(2*NumSamples)); /* Left and right */
184
185 }
186
187 /*
188 * Mix DBE processed path and bypass volume path
189 */
190 LVC_MixSoft_2St_D16C31_SAT(&pInstance->pData->BypassMixer,
191 (LVM_INT16 *) pScratch,
192 pScratchVol,
193 pOutData,
194 (LVM_INT16)(2*NumSamples));
195
196 return(LVDBE_SUCCESS);
197 }
198
199
200
201
202
203
204
205
206
207
208