blob: 80e76d4aebf399190f29156a85bee5786676be4f [file] [log] [blame]
Chih-Chung Chang99698662011-06-30 14:21:38 +08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_NDEBUG 1
18#define LOG_TAG "VideoEditorBGAudioProcessing"
19#include <utils/Log.h>
20#include "VideoEditorBGAudioProcessing.h"
21
22namespace android {
23
24VideoEditorBGAudioProcessing::VideoEditorBGAudioProcessing() {
25
Steve Block2703f232011-10-20 11:56:09 +010026 ALOGV("VideoEditorBGAudioProcessing:: Construct VideoEditorBGAudioProcessing ");
Chih-Chung Chang99698662011-06-30 14:21:38 +080027
28 mAudVolArrIndex = 0;
29 mDoDucking = 0;
30 mDucking_enable = 0;
31 mDucking_lowVolume = 0;
32 mDucking_threshold = 0;
33 mDuckingFactor = 0;
34
35 mBTVolLevel = 0;
36 mPTVolLevel = 0;
37
38 mIsSSRCneeded = 0;
39 mChannelConversion = 0;
40
41 mBTFormat = MONO_16_BIT;
42
43 mInSampleRate = 8000;
44 mOutSampleRate = 16000;
45 mPTChannelCount = 2;
46 mBTChannelCount = 1;
47}
48
49M4OSA_Int32 VideoEditorBGAudioProcessing::veProcessAudioMixNDuck(
50 void *pPTBuffer, void *pBTBuffer, void *pOutBuffer) {
51
52 M4AM_Buffer16* pPrimaryTrack = (M4AM_Buffer16*)pPTBuffer;
53 M4AM_Buffer16* pBackgroundTrack = (M4AM_Buffer16*)pBTBuffer;
54 M4AM_Buffer16* pMixedOutBuffer = (M4AM_Buffer16*)pOutBuffer;
55
Steve Block2703f232011-10-20 11:56:09 +010056 ALOGV("VideoEditorBGAudioProcessing::lvProcessAudioMixNDuck \
Chih-Chung Chang99698662011-06-30 14:21:38 +080057 pPTBuffer 0x%x pBTBuffer 0x%x pOutBuffer 0x%x", pPTBuffer,
58 pBTBuffer, pOutBuffer);
59
60 M4OSA_ERR result = M4NO_ERROR;
61 M4OSA_Int16 *pBTMdata1;
62 M4OSA_Int16 *pPTMdata2;
63 M4OSA_UInt32 uiPCMsize;
64
65 // Ducking variable
66 M4OSA_UInt16 loopIndex = 0;
67 M4OSA_Int16 *pPCM16Sample = M4OSA_NULL;
68 M4OSA_Int32 peakDbValue = 0;
69 M4OSA_Int32 previousDbValue = 0;
70 M4OSA_UInt32 i;
71
72 // Output size if same as PT size
73 pMixedOutBuffer->m_bufferSize = pPrimaryTrack->m_bufferSize;
74
75 // Before mixing, we need to have only PT as out buffer
76 memcpy((void *)pMixedOutBuffer->m_dataAddress,
77 (void *)pPrimaryTrack->m_dataAddress, pMixedOutBuffer->m_bufferSize);
78
79 // Initially contains the input primary track
80 pPTMdata2 = (M4OSA_Int16*)pMixedOutBuffer->m_dataAddress;
81 // Contains BG track processed data(like channel conversion etc..
82 pBTMdata1 = (M4OSA_Int16*) pBackgroundTrack->m_dataAddress;
83
84 // Since we need to give sample count and not buffer size
85 uiPCMsize = pMixedOutBuffer->m_bufferSize/2 ;
86
87 if ((mDucking_enable) && (mPTVolLevel != 0.0)) {
88 // LOGI("VideoEditorBGAudioProcessing:: In Ducking analysis ");
89 loopIndex = 0;
90 peakDbValue = 0;
91 previousDbValue = peakDbValue;
92
93 pPCM16Sample = (M4OSA_Int16*)pPrimaryTrack->m_dataAddress;
94
95 while (loopIndex < pPrimaryTrack->m_bufferSize/sizeof(M4OSA_Int16)) {
96 if (pPCM16Sample[loopIndex] >= 0) {
97 peakDbValue = previousDbValue > pPCM16Sample[loopIndex] ?
98 previousDbValue : pPCM16Sample[loopIndex];
99 previousDbValue = peakDbValue;
100 } else {
101 peakDbValue = previousDbValue > -pPCM16Sample[loopIndex] ?
102 previousDbValue: -pPCM16Sample[loopIndex];
103 previousDbValue = peakDbValue;
104 }
105 loopIndex++;
106 }
107
108 mAudioVolumeArray[mAudVolArrIndex] = getDecibelSound(peakDbValue);
109
Steve Block2703f232011-10-20 11:56:09 +0100110 ALOGV("VideoEditorBGAudioProcessing:: getDecibelSound %d",
Chih-Chung Chang99698662011-06-30 14:21:38 +0800111 mAudioVolumeArray[mAudVolArrIndex]);
112
113 // WINDOW_SIZE is 10 by default
114 // Check for threshold is done after 10 cycles
115 if (mAudVolArrIndex >= WINDOW_SIZE - 1) {
116 mDoDucking = isThresholdBreached(mAudioVolumeArray,
117 mAudVolArrIndex,mDucking_threshold );
118 mAudVolArrIndex = 0;
119 } else {
120 mAudVolArrIndex++;
121 }
122
123 //
124 // Below logic controls the mixing weightage
125 // for Background and Primary Tracks
126 // for the duration of window under analysis,
127 // to give fade-out for Background and fade-in for primary
128 // Current fading factor is distributed in equal range over
129 // the defined window size.
130 // For a window size = 25
131 // (500 ms (window under analysis) / 20 ms (sample duration))
132 //
133
134 if (mDoDucking) {
135 if (mDuckingFactor > mDucking_lowVolume) {
136 // FADE OUT BG Track
137 // Increment ducking factor in total steps in factor
138 // of low volume steps to reach low volume level
139 mDuckingFactor -= (mDucking_lowVolume);
140 } else {
141 mDuckingFactor = mDucking_lowVolume;
142 }
143 } else {
144 if (mDuckingFactor < 1.0 ) {
145 // FADE IN BG Track
146 // Increment ducking factor in total steps of
147 // low volume factor to reach orig.volume level
148 mDuckingFactor += (mDucking_lowVolume);
149 } else {
150 mDuckingFactor = 1.0;
151 }
152 }
153 } // end if - mDucking_enable
154
155
156 // Mixing Logic
157
Steve Block2703f232011-10-20 11:56:09 +0100158 ALOGV("VideoEditorBGAudioProcessing:: Out of Ducking analysis uiPCMsize\
Chih-Chung Chang99698662011-06-30 14:21:38 +0800159 %d %f %f", mDoDucking, mDuckingFactor,mBTVolLevel);
160
161 while (uiPCMsize-- > 0) {
162
163 M4OSA_Int32 temp;
164 // Set vol factor for BT and PT
165 *pBTMdata1 = (M4OSA_Int16)(*pBTMdata1*mBTVolLevel);
166 *pPTMdata2 = (M4OSA_Int16)(*pPTMdata2*mPTVolLevel);
167
168 // Mix the two samples
169 if (mDoDucking) {
170
171 // Duck the BG track to ducking factor value before mixing
172 *pBTMdata1 = (M4OSA_Int16)((*pBTMdata1)*(mDuckingFactor));
173
174 // mix as normal case
175 *pBTMdata1 = (M4OSA_Int16)(*pBTMdata1 /2 + *pPTMdata2 /2);
176 } else {
177
178 *pBTMdata1 = (M4OSA_Int16)((*pBTMdata1)*(mDuckingFactor));
179 *pBTMdata1 = (M4OSA_Int16)(*pBTMdata1 /2 + *pPTMdata2 /2);
180 }
181
182 if (*pBTMdata1 < 0) {
183 temp = -(*pBTMdata1) * 2; // bring to original Amplitude level
184
185 if (temp > 32767) {
186 *pBTMdata1 = -32766; // less then max allowed value
187 } else {
188 *pBTMdata1 = (M4OSA_Int16)(-temp);
189 }
190 } else {
191 temp = (*pBTMdata1) * 2; // bring to original Amplitude level
192 if ( temp > 32768) {
193 *pBTMdata1 = 32767; // less than max allowed value
194 } else {
195 *pBTMdata1 = (M4OSA_Int16)temp;
196 }
197 }
198
199 pBTMdata1++;
200 pPTMdata2++;
201 }
Steve Block2703f232011-10-20 11:56:09 +0100202 //ALOGV("VideoEditorBGAudioProcessing:: Copy final out ");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800203 memcpy((void *)pMixedOutBuffer->m_dataAddress,
204 (void *)pBackgroundTrack->m_dataAddress,
205 pBackgroundTrack->m_bufferSize);
206
Steve Block2703f232011-10-20 11:56:09 +0100207 ALOGV("VideoEditorBGAudioProcessing::lvProcessAudioMixNDuck EXIT");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800208 return result;
209}
210
211VideoEditorBGAudioProcessing::~VideoEditorBGAudioProcessing() {
212
213}
214
215M4OSA_Int32 VideoEditorBGAudioProcessing::calculateOutResampleBufSize() {
216
217 // This already takes care of channel count in mBTBuffer.m_bufferSize
218 return (mOutSampleRate / mInSampleRate) * mBTBuffer.m_bufferSize;
219}
220
221void VideoEditorBGAudioProcessing ::veSetAudioProcessingParams(
222 const veAudMixSettings& gInputParams) {
223
Steve Block2703f232011-10-20 11:56:09 +0100224 ALOGV("VideoEditorBGAudioProcessing:: ENTER lvSetAudioProcessingParams ");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800225 mDucking_enable = gInputParams.lvInDucking_enable;
226 mDucking_lowVolume = gInputParams.lvInDucking_lowVolume;
227 mDucking_threshold = gInputParams.lvInDucking_threshold;
228
229 mPTVolLevel = gInputParams.lvPTVolLevel;
230 mBTVolLevel = gInputParams.lvBTVolLevel ;
231
232 mBTChannelCount = gInputParams.lvBTChannelCount;
233 mPTChannelCount = gInputParams.lvPTChannelCount;
234
235 mBTFormat = gInputParams.lvBTFormat;
236
237 mInSampleRate = gInputParams.lvInSampleRate;
238 mOutSampleRate = gInputParams.lvOutSampleRate;
239
240 mAudVolArrIndex = 0;
241 mDoDucking = 0;
242 mDuckingFactor = 1.0; // default
243
Steve Block2703f232011-10-20 11:56:09 +0100244 ALOGV("VideoEditorBGAudioProcessing:: ducking_enable 0x%x \
Chih-Chung Chang99698662011-06-30 14:21:38 +0800245 ducking_lowVolume %f ducking_threshold %d fPTVolLevel %f BTVolLevel %f",
246 mDucking_enable, mDucking_lowVolume, mDucking_threshold,
247 mPTVolLevel, mPTVolLevel);
248
249 // Following logc decides if SSRC support is needed for this mixing
250 mIsSSRCneeded = (gInputParams.lvInSampleRate != gInputParams.lvOutSampleRate);
251 if (gInputParams.lvBTChannelCount != gInputParams.lvPTChannelCount){
252 if (gInputParams.lvBTChannelCount == 2){
253 mChannelConversion = 1; // convert to MONO
254 } else {
255 mChannelConversion = 2; // Convert to STEREO
256 }
257 } else {
258 mChannelConversion = 0;
259 }
Steve Block2703f232011-10-20 11:56:09 +0100260 ALOGV("VideoEditorBGAudioProcessing:: EXIT veSetAudioProcessingParams ");
Chih-Chung Chang99698662011-06-30 14:21:38 +0800261}
262
263
264// Fast way to compute 10 * log(value)
265M4OSA_Int32 VideoEditorBGAudioProcessing::getDecibelSound(M4OSA_UInt32 value) {
266 if (value <= 0 || value > 0x8000) {
267 return 0;
268 } else if (value > 0x4000) { // 32768
269 return 90;
270 } else if (value > 0x2000) { // 16384
271 return 84;
272 } else if (value > 0x1000) { // 8192
273 return 78;
274 } else if (value > 0x0800) { // 4028
275 return 72;
276 } else if (value > 0x0400) { // 2048
277 return 66;
278 } else if (value > 0x0200) { // 1024
279 return 60;
280 } else if (value > 0x0100) { // 512
281 return 54;
282 } else if (value > 0x0080) { // 256
283 return 48;
284 } else if (value > 0x0040) { // 128
285 return 42;
286 } else if (value > 0x0020) { // 64
287 return 36;
288 } else if (value > 0x0010) { // 32
289 return 30;
290 } else if (value > 0x0008) { // 16
291 return 24;
292 } else if (value > 0x0007) { // 8
293 return 24;
294 } else if (value > 0x0003) { // 4
295 return 18;
296 } else if (value > 0x0001) { // 2
297 return 12;
298 } else { // 1
299 return 6;
300 }
301}
302
303M4OSA_Bool VideoEditorBGAudioProcessing::isThresholdBreached(
304 M4OSA_Int32* averageValue,
305 M4OSA_Int32 storeCount,
306 M4OSA_Int32 thresholdValue) {
307
308 int totalValue = 0;
309 for (int i = 0; i < storeCount; ++i) {
310 totalValue += averageValue[i];
311 }
312 return (totalValue / storeCount > thresholdValue);
313}
314
315}//namespace android