blob: bcdc3deb75f2887fe6ed9f0e19f086c4899d3c69 [file] [log] [blame]
Dharmaray Kundargi643290d2011-01-16 16:02:42 -08001/*
2 * Copyright (C) 2011 NXP Software
3 * Copyright (C) 2011 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#define LOG_NDEBUG 1
19#define LOG_TAG "VideoEditorBGAudioProcessing"
20#include <utils/Log.h>
21#include "VideoEditorBGAudioProcessing.h"
22
23namespace android {
24
James Dong3b9ba852011-05-03 23:31:23 -070025VideoEditorBGAudioProcessing::VideoEditorBGAudioProcessing() {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080026
27 LOGV("VideoEditorBGAudioProcessing:: Construct VideoEditorBGAudioProcessing ");
28
James Dong3b9ba852011-05-03 23:31:23 -070029 mAudVolArrIndex = 0;
30 mDoDucking = 0;
31 mDucking_enable = 0;
32 mDucking_lowVolume = 0;
33 mDucking_threshold = 0;
34 mDuckingFactor = 0;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080035
James Dong3b9ba852011-05-03 23:31:23 -070036 mBTVolLevel = 0;
37 mPTVolLevel = 0;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080038
James Dong3b9ba852011-05-03 23:31:23 -070039 mIsSSRCneeded = 0;
40 mChannelConversion = 0;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080041
James Dong3b9ba852011-05-03 23:31:23 -070042 mBTFormat = MONO_16_BIT;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080043
James Dong3b9ba852011-05-03 23:31:23 -070044 mInSampleRate = 8000;
45 mOutSampleRate = 16000;
46 mPTChannelCount = 2;
47 mBTChannelCount = 1;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080048}
49
50M4OSA_Int32 VideoEditorBGAudioProcessing::veProcessAudioMixNDuck(
51 void *pPTBuffer, void *pBTBuffer, void *pOutBuffer) {
52
Rajneesh Chowdury1c97d9a2011-02-21 15:43:33 -080053 M4AM_Buffer16* pPrimaryTrack = (M4AM_Buffer16*)pPTBuffer;
54 M4AM_Buffer16* pBackgroundTrack = (M4AM_Buffer16*)pBTBuffer;
55 M4AM_Buffer16* pMixedOutBuffer = (M4AM_Buffer16*)pOutBuffer;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080056
57 LOGV("VideoEditorBGAudioProcessing::lvProcessAudioMixNDuck \
James Dong3b9ba852011-05-03 23:31:23 -070058 pPTBuffer 0x%x pBTBuffer 0x%x pOutBuffer 0x%x", pPTBuffer,
59 pBTBuffer, pOutBuffer);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080060
61 M4OSA_ERR result = M4NO_ERROR;
62 M4OSA_Int16 *pBTMdata1;
63 M4OSA_Int16 *pPTMdata2;
64 M4OSA_UInt32 uiPCMsize;
65
66 // Ducking variable
67 M4OSA_UInt16 loopIndex = 0;
68 M4OSA_Int16 *pPCM16Sample = M4OSA_NULL;
69 M4OSA_Int32 peakDbValue = 0;
70 M4OSA_Int32 previousDbValue = 0;
71 M4OSA_UInt32 i;
72
73 // Output size if same as PT size
74 pMixedOutBuffer->m_bufferSize = pPrimaryTrack->m_bufferSize;
75
76 // Before mixing, we need to have only PT as out buffer
Shyam Pallapothu32ed3f42011-04-20 21:00:48 -070077 memcpy((void *)pMixedOutBuffer->m_dataAddress,
James Dong3b9ba852011-05-03 23:31:23 -070078 (void *)pPrimaryTrack->m_dataAddress, pMixedOutBuffer->m_bufferSize);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080079
80 // Initially contains the input primary track
81 pPTMdata2 = (M4OSA_Int16*)pMixedOutBuffer->m_dataAddress;
82 // Contains BG track processed data(like channel conversion etc..
83 pBTMdata1 = (M4OSA_Int16*) pBackgroundTrack->m_dataAddress;
84
85 // Since we need to give sample count and not buffer size
86 uiPCMsize = pMixedOutBuffer->m_bufferSize/2 ;
87
James Dong3b9ba852011-05-03 23:31:23 -070088 if ((mDucking_enable) && (mPTVolLevel != 0.0)) {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080089 // LOGI("VideoEditorBGAudioProcessing:: In Ducking analysis ");
90 loopIndex = 0;
91 peakDbValue = 0;
92 previousDbValue = peakDbValue;
93
94 pPCM16Sample = (M4OSA_Int16*)pPrimaryTrack->m_dataAddress;
95
James Dong3b9ba852011-05-03 23:31:23 -070096 while (loopIndex < pPrimaryTrack->m_bufferSize/sizeof(M4OSA_Int16)) {
97 if (pPCM16Sample[loopIndex] >= 0) {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -080098 peakDbValue = previousDbValue > pPCM16Sample[loopIndex] ?
James Dong3b9ba852011-05-03 23:31:23 -070099 previousDbValue : pPCM16Sample[loopIndex];
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800100 previousDbValue = peakDbValue;
James Dong3b9ba852011-05-03 23:31:23 -0700101 } else {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800102 peakDbValue = previousDbValue > -pPCM16Sample[loopIndex] ?
James Dong3b9ba852011-05-03 23:31:23 -0700103 previousDbValue: -pPCM16Sample[loopIndex];
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800104 previousDbValue = peakDbValue;
105 }
106 loopIndex++;
107 }
108
James Dong3b9ba852011-05-03 23:31:23 -0700109 mAudioVolumeArray[mAudVolArrIndex] = getDecibelSound(peakDbValue);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800110
111 LOGV("VideoEditorBGAudioProcessing:: getDecibelSound %d",
James Dong3b9ba852011-05-03 23:31:23 -0700112 mAudioVolumeArray[mAudVolArrIndex]);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800113
114 // WINDOW_SIZE is 10 by default
115 // Check for threshold is done after 10 cycles
James Dong3b9ba852011-05-03 23:31:23 -0700116 if (mAudVolArrIndex >= WINDOW_SIZE - 1) {
117 mDoDucking = isThresholdBreached(mAudioVolumeArray,
118 mAudVolArrIndex,mDucking_threshold );
119 mAudVolArrIndex = 0;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800120 } else {
James Dong3b9ba852011-05-03 23:31:23 -0700121 mAudVolArrIndex++;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800122 }
123
124 //
125 // Below logic controls the mixing weightage
126 // for Background and Primary Tracks
127 // for the duration of window under analysis,
128 // to give fade-out for Background and fade-in for primary
129 // Current fading factor is distributed in equal range over
130 // the defined window size.
131 // For a window size = 25
132 // (500 ms (window under analysis) / 20 ms (sample duration))
133 //
134
James Dong3b9ba852011-05-03 23:31:23 -0700135 if (mDoDucking) {
136 if (mDuckingFactor > mDucking_lowVolume) {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800137 // FADE OUT BG Track
138 // Increment ducking factor in total steps in factor
139 // of low volume steps to reach low volume level
James Dong3b9ba852011-05-03 23:31:23 -0700140 mDuckingFactor -= (mDucking_lowVolume);
141 } else {
142 mDuckingFactor = mDucking_lowVolume;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800143 }
144 } else {
James Dong3b9ba852011-05-03 23:31:23 -0700145 if (mDuckingFactor < 1.0 ) {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800146 // FADE IN BG Track
147 // Increment ducking factor in total steps of
148 // low volume factor to reach orig.volume level
James Dong3b9ba852011-05-03 23:31:23 -0700149 mDuckingFactor += (mDucking_lowVolume);
150 } else {
151 mDuckingFactor = 1.0;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800152 }
153 }
154 } // end if - mDucking_enable
155
156
157 // Mixing Logic
158
159 LOGV("VideoEditorBGAudioProcessing:: Out of Ducking analysis uiPCMsize\
James Dong3b9ba852011-05-03 23:31:23 -0700160 %d %f %f", mDoDucking, mDuckingFactor,mBTVolLevel);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800161
James Dong3b9ba852011-05-03 23:31:23 -0700162 while (uiPCMsize-- > 0) {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800163
164 M4OSA_Int32 temp;
165 // Set vol factor for BT and PT
James Dong3b9ba852011-05-03 23:31:23 -0700166 *pBTMdata1 = (M4OSA_Int16)(*pBTMdata1*mBTVolLevel);
167 *pPTMdata2 = (M4OSA_Int16)(*pPTMdata2*mPTVolLevel);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800168
169 // Mix the two samples
James Dong3b9ba852011-05-03 23:31:23 -0700170 if (mDoDucking) {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800171
172 // Duck the BG track to ducking factor value before mixing
James Dong3b9ba852011-05-03 23:31:23 -0700173 *pBTMdata1 = (M4OSA_Int16)((*pBTMdata1)*(mDuckingFactor));
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800174
175 // mix as normal case
176 *pBTMdata1 = (M4OSA_Int16)(*pBTMdata1 /2 + *pPTMdata2 /2);
James Dong3b9ba852011-05-03 23:31:23 -0700177 } else {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800178
James Dong3b9ba852011-05-03 23:31:23 -0700179 *pBTMdata1 = (M4OSA_Int16)((*pBTMdata1)*(mDuckingFactor));
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800180 *pBTMdata1 = (M4OSA_Int16)(*pBTMdata1 /2 + *pPTMdata2 /2);
181 }
182
James Dong3b9ba852011-05-03 23:31:23 -0700183 if (*pBTMdata1 < 0) {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800184 temp = -(*pBTMdata1) * 2; // bring to original Amplitude level
185
James Dong3b9ba852011-05-03 23:31:23 -0700186 if (temp > 32767) {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800187 *pBTMdata1 = -32766; // less then max allowed value
James Dong3b9ba852011-05-03 23:31:23 -0700188 } else {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800189 *pBTMdata1 = (M4OSA_Int16)(-temp);
190 }
James Dong3b9ba852011-05-03 23:31:23 -0700191 } else {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800192 temp = (*pBTMdata1) * 2; // bring to original Amplitude level
193 if ( temp > 32768) {
194 *pBTMdata1 = 32767; // less than max allowed value
James Dong3b9ba852011-05-03 23:31:23 -0700195 } else {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800196 *pBTMdata1 = (M4OSA_Int16)temp;
197 }
198 }
199
200 pBTMdata1++;
201 pPTMdata2++;
202 }
203 //LOGV("VideoEditorBGAudioProcessing:: Copy final out ");
Shyam Pallapothu32ed3f42011-04-20 21:00:48 -0700204 memcpy((void *)pMixedOutBuffer->m_dataAddress,
James Dong3b9ba852011-05-03 23:31:23 -0700205 (void *)pBackgroundTrack->m_dataAddress,
206 pBackgroundTrack->m_bufferSize);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800207
208 LOGV("VideoEditorBGAudioProcessing::lvProcessAudioMixNDuck EXIT");
209 return result;
210}
211
James Dong3b9ba852011-05-03 23:31:23 -0700212VideoEditorBGAudioProcessing::~VideoEditorBGAudioProcessing() {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800213
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800214}
215
216M4OSA_Int32 VideoEditorBGAudioProcessing::calculateOutResampleBufSize() {
217
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800218 // This already takes care of channel count in mBTBuffer.m_bufferSize
James Dong3b9ba852011-05-03 23:31:23 -0700219 return (mOutSampleRate / mInSampleRate) * mBTBuffer.m_bufferSize;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800220}
221
222void VideoEditorBGAudioProcessing ::veSetAudioProcessingParams(
James Dong3b9ba852011-05-03 23:31:23 -0700223 const veAudMixSettings& gInputParams) {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800224
225 LOGV("VideoEditorBGAudioProcessing:: ENTER lvSetAudioProcessingParams ");
James Dong3b9ba852011-05-03 23:31:23 -0700226 mDucking_enable = gInputParams.lvInDucking_enable;
227 mDucking_lowVolume = gInputParams.lvInDucking_lowVolume;
228 mDucking_threshold = gInputParams.lvInDucking_threshold;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800229
James Dong3b9ba852011-05-03 23:31:23 -0700230 mPTVolLevel = gInputParams.lvPTVolLevel;
231 mBTVolLevel = gInputParams.lvBTVolLevel ;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800232
James Dong3b9ba852011-05-03 23:31:23 -0700233 mBTChannelCount = gInputParams.lvBTChannelCount;
234 mPTChannelCount = gInputParams.lvPTChannelCount;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800235
James Dong3b9ba852011-05-03 23:31:23 -0700236 mBTFormat = gInputParams.lvBTFormat;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800237
James Dong3b9ba852011-05-03 23:31:23 -0700238 mInSampleRate = gInputParams.lvInSampleRate;
239 mOutSampleRate = gInputParams.lvOutSampleRate;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800240
James Dong3b9ba852011-05-03 23:31:23 -0700241 mAudVolArrIndex = 0;
242 mDoDucking = 0;
243 mDuckingFactor = 1.0; // default
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800244
245 LOGV("VideoEditorBGAudioProcessing:: ducking_enable 0x%x \
James Dong3b9ba852011-05-03 23:31:23 -0700246 ducking_lowVolume %f ducking_threshold %d fPTVolLevel %f BTVolLevel %f",
247 mDucking_enable, mDucking_lowVolume, mDucking_threshold,
248 mPTVolLevel, mPTVolLevel);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800249
250 // Following logc decides if SSRC support is needed for this mixing
James Dong3b9ba852011-05-03 23:31:23 -0700251 mIsSSRCneeded = (gInputParams.lvInSampleRate != gInputParams.lvOutSampleRate);
252 if (gInputParams.lvBTChannelCount != gInputParams.lvPTChannelCount){
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800253 if (gInputParams.lvBTChannelCount == 2){
James Dong3b9ba852011-05-03 23:31:23 -0700254 mChannelConversion = 1; // convert to MONO
255 } else {
256 mChannelConversion = 2; // Convert to STEREO
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800257 }
James Dong3b9ba852011-05-03 23:31:23 -0700258 } else {
259 mChannelConversion = 0;
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800260 }
261 LOGV("VideoEditorBGAudioProcessing:: EXIT veSetAudioProcessingParams ");
262}
263
264
James Dong3b9ba852011-05-03 23:31:23 -0700265// Fast way to compute 10 * log(value)
266M4OSA_Int32 VideoEditorBGAudioProcessing::getDecibelSound(M4OSA_UInt32 value) {
267 if (value <= 0 || value > 0x8000) {
268 return 0;
269 } else if (value > 0x4000) { // 32768
270 return 90;
271 } else if (value > 0x2000) { // 16384
272 return 84;
273 } else if (value > 0x1000) { // 8192
274 return 78;
275 } else if (value > 0x0800) { // 4028
276 return 72;
277 } else if (value > 0x0400) { // 2048
278 return 66;
279 } else if (value > 0x0200) { // 1024
280 return 60;
281 } else if (value > 0x0100) { // 512
282 return 54;
283 } else if (value > 0x0080) { // 256
284 return 48;
285 } else if (value > 0x0040) { // 128
286 return 42;
287 } else if (value > 0x0020) { // 64
288 return 36;
289 } else if (value > 0x0010) { // 32
290 return 30;
291 } else if (value > 0x0008) { // 16
292 return 24;
293 } else if (value > 0x0007) { // 8
294 return 24;
295 } else if (value > 0x0003) { // 4
296 return 18;
297 } else if (value > 0x0001) { // 2
298 return 12;
299 } else { // 1
300 return 6;
301 }
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800302}
303
James Dong3b9ba852011-05-03 23:31:23 -0700304M4OSA_Bool VideoEditorBGAudioProcessing::isThresholdBreached(
305 M4OSA_Int32* averageValue,
306 M4OSA_Int32 storeCount,
307 M4OSA_Int32 thresholdValue) {
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800308
James Dong3b9ba852011-05-03 23:31:23 -0700309 int totalValue = 0;
310 for (int i = 0; i < storeCount; ++i) {
311 totalValue += averageValue[i];
312 }
313 return (totalValue / storeCount > thresholdValue);
Dharmaray Kundargi643290d2011-01-16 16:02:42 -0800314}
315
316}//namespace android