blob: 28208d135ff24cb306a80ee132d4b4b3e6069fe6 [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
25VideoEditorBGAudioProcessing ::VideoEditorBGAudioProcessing() {
26
27 LOGV("VideoEditorBGAudioProcessing:: Construct VideoEditorBGAudioProcessing ");
28
29 VideoEditorBGAudioProcessing::mAudVolArrIndex = 0;
30 VideoEditorBGAudioProcessing::mDoDucking = 0;
31 VideoEditorBGAudioProcessing::mDucking_enable = 0;
32 VideoEditorBGAudioProcessing::mDucking_lowVolume = 0;
33 VideoEditorBGAudioProcessing::mDucking_threshold = 0;
34 VideoEditorBGAudioProcessing::mDuckingFactor = 0;
35
36 VideoEditorBGAudioProcessing::mBTVolLevel = 0;
37 VideoEditorBGAudioProcessing::mPTVolLevel = 0;
38
39 VideoEditorBGAudioProcessing::mIsSSRCneeded = 0;
40 VideoEditorBGAudioProcessing::mChannelConversion = 0;
41
42 VideoEditorBGAudioProcessing::mBTFormat = MONO_16_BIT;
43
44 VideoEditorBGAudioProcessing::mInSampleRate = 8000;
45 VideoEditorBGAudioProcessing::mOutSampleRate = 16000;
46 VideoEditorBGAudioProcessing::mPTChannelCount = 2;
47 VideoEditorBGAudioProcessing::mBTChannelCount = 1;
48}
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 \
58 pPTBuffer 0x%x pBTBuffer 0x%x pOutBuffer 0x%x", pPTBuffer,
59 pBTBuffer, pOutBuffer);
60
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
77 M4OSA_memcpy((M4OSA_MemAddr8)pMixedOutBuffer->m_dataAddress,
78 (M4OSA_MemAddr8)pPrimaryTrack->m_dataAddress, pMixedOutBuffer->m_bufferSize);
79
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
88 if((this->mDucking_enable) && (this->mPTVolLevel != 0.0)) {
89 // LOGI("VideoEditorBGAudioProcessing:: In Ducking analysis ");
90 loopIndex = 0;
91 peakDbValue = 0;
92 previousDbValue = peakDbValue;
93
94 pPCM16Sample = (M4OSA_Int16*)pPrimaryTrack->m_dataAddress;
95
96 while( loopIndex < pPrimaryTrack->m_bufferSize/sizeof(M4OSA_Int16))
97 {
98 if (pPCM16Sample[loopIndex] >= 0){
99 peakDbValue = previousDbValue > pPCM16Sample[loopIndex] ?
100 previousDbValue : pPCM16Sample[loopIndex];
101 previousDbValue = peakDbValue;
102 }else{
103 peakDbValue = previousDbValue > -pPCM16Sample[loopIndex] ?
104 previousDbValue: -pPCM16Sample[loopIndex];
105 previousDbValue = peakDbValue;
106 }
107 loopIndex++;
108 }
109
110 this->mAudioVolumeArray[this->mAudVolArrIndex] =
111 getDecibelSound(peakDbValue);
112
113 LOGV("VideoEditorBGAudioProcessing:: getDecibelSound %d",
114 this->mAudioVolumeArray[this->mAudVolArrIndex]);
115
116 // WINDOW_SIZE is 10 by default
117 // Check for threshold is done after 10 cycles
118 if ( this->mAudVolArrIndex >= WINDOW_SIZE -1) {
119 this->mDoDucking = isThresholdBreached(this->mAudioVolumeArray,
120 this->mAudVolArrIndex,this->mDucking_threshold );
121
122 this->mAudVolArrIndex = 0;
123 } else {
124 this->mAudVolArrIndex++;
125 }
126
127 //
128 // Below logic controls the mixing weightage
129 // for Background and Primary Tracks
130 // for the duration of window under analysis,
131 // to give fade-out for Background and fade-in for primary
132 // Current fading factor is distributed in equal range over
133 // the defined window size.
134 // For a window size = 25
135 // (500 ms (window under analysis) / 20 ms (sample duration))
136 //
137
138 if(this->mDoDucking){
139 if ( this->mDuckingFactor > this->mDucking_lowVolume) {
140 // FADE OUT BG Track
141 // Increment ducking factor in total steps in factor
142 // of low volume steps to reach low volume level
143 this->mDuckingFactor -= (this->mDucking_lowVolume);
144 }
145 else {
146 this->mDuckingFactor = this->mDucking_lowVolume;
147 }
148 } else {
149 if ( this->mDuckingFactor < 1.0 ){
150 // FADE IN BG Track
151 // Increment ducking factor in total steps of
152 // low volume factor to reach orig.volume level
153 this->mDuckingFactor += (this->mDucking_lowVolume);
154 }
155 else{
156 this->mDuckingFactor = 1.0;
157 }
158 }
159 } // end if - mDucking_enable
160
161
162 // Mixing Logic
163
164 LOGV("VideoEditorBGAudioProcessing:: Out of Ducking analysis uiPCMsize\
165 %d %f %f", this->mDoDucking, this->mDuckingFactor,this->mBTVolLevel);
166
167 while(uiPCMsize-->0) {
168
169 M4OSA_Int32 temp;
170 // Set vol factor for BT and PT
171 *pBTMdata1 = (M4OSA_Int16)(*pBTMdata1*this->mBTVolLevel);
172 *pPTMdata2 = (M4OSA_Int16)(*pPTMdata2*this->mPTVolLevel);
173
174 // Mix the two samples
175 if ( this->mDoDucking) {
176
177 // Duck the BG track to ducking factor value before mixing
178 *pBTMdata1 = (M4OSA_Int16)((*pBTMdata1)*(this->mDuckingFactor));
179
180 // mix as normal case
181 *pBTMdata1 = (M4OSA_Int16)(*pBTMdata1 /2 + *pPTMdata2 /2);
182 }
183 else {
184
185 *pBTMdata1 = (M4OSA_Int16)((*pBTMdata1)*(this->mDuckingFactor));
186 *pBTMdata1 = (M4OSA_Int16)(*pBTMdata1 /2 + *pPTMdata2 /2);
187 }
188
189 if ( *pBTMdata1 < 0) {
190 temp = -(*pBTMdata1) * 2; // bring to original Amplitude level
191
192 if ( temp > 32767) {
193 *pBTMdata1 = -32766; // less then max allowed value
194 }
195 else{
196 *pBTMdata1 = (M4OSA_Int16)(-temp);
197 }
198 }
199 else {
200 temp = (*pBTMdata1) * 2; // bring to original Amplitude level
201 if ( temp > 32768) {
202 *pBTMdata1 = 32767; // less than max allowed value
203 }
204 else {
205 *pBTMdata1 = (M4OSA_Int16)temp;
206 }
207 }
208
209 pBTMdata1++;
210 pPTMdata2++;
211 }
212 //LOGV("VideoEditorBGAudioProcessing:: Copy final out ");
213 M4OSA_memcpy((M4OSA_MemAddr8)pMixedOutBuffer->m_dataAddress,
214 (M4OSA_MemAddr8)pBackgroundTrack->m_dataAddress,
215 pBackgroundTrack->m_bufferSize);
216
217 LOGV("VideoEditorBGAudioProcessing::lvProcessAudioMixNDuck EXIT");
218 return result;
219}
220
221VideoEditorBGAudioProcessing:: ~VideoEditorBGAudioProcessing() {
222
223 //free(VideoEditorBGAudioProcessing:: pTempBuffer);
224}
225
226M4OSA_Int32 VideoEditorBGAudioProcessing::calculateOutResampleBufSize() {
227
228 M4OSA_Int32 bufSize =0;
229
230 // This already takes care of channel count in mBTBuffer.m_bufferSize
231 bufSize = (this->mOutSampleRate/this->mInSampleRate)*this->mBTBuffer.m_bufferSize;
232
233 return bufSize;
234}
235
236void VideoEditorBGAudioProcessing ::veSetAudioProcessingParams(
237 veAudMixSettings gInputParams) {
238
239 LOGV("VideoEditorBGAudioProcessing:: ENTER lvSetAudioProcessingParams ");
240 this->mDucking_enable = gInputParams.lvInDucking_enable;
241 this->mDucking_lowVolume = gInputParams.lvInDucking_lowVolume;
242 this->mDucking_threshold = gInputParams.lvInDucking_threshold;
243
244 this->mPTVolLevel = gInputParams.lvPTVolLevel;
245 this->mBTVolLevel = gInputParams.lvBTVolLevel ;
246
247 this->mBTChannelCount = gInputParams.lvBTChannelCount;
248 this->mPTChannelCount = gInputParams.lvPTChannelCount;
249
250 this->mBTFormat = gInputParams.lvBTFormat;
251
252 this->mInSampleRate = gInputParams.lvInSampleRate;
253 this->mOutSampleRate = gInputParams.lvOutSampleRate;
254
255 this->mAudVolArrIndex = 0;
256 this->mDoDucking = 0;
257 this->mDuckingFactor = 1.0; // default
258
259 LOGV("VideoEditorBGAudioProcessing:: ducking_enable 0x%x \
260 ducking_lowVolume %f ducking_threshold %d fPTVolLevel %f BTVolLevel %f",
261 this->mDucking_enable, this->mDucking_lowVolume, this->mDucking_threshold,
262 this->mPTVolLevel, this->mPTVolLevel);
263
264 // Following logc decides if SSRC support is needed for this mixing
265 if ( gInputParams.lvInSampleRate != gInputParams.lvOutSampleRate){
266 this->mIsSSRCneeded = 1;
267 }else{
268 this->mIsSSRCneeded = 0;
269 }
270 if( gInputParams.lvBTChannelCount != gInputParams.lvPTChannelCount){
271 if (gInputParams.lvBTChannelCount == 2){
272 this->mChannelConversion = 1; // convert to MONO
273 }else{
274 this->mChannelConversion = 2; // Convert to STEREO
275 }
276 }else{
277 this->mChannelConversion = 0;
278 }
279 LOGV("VideoEditorBGAudioProcessing:: EXIT veSetAudioProcessingParams ");
280}
281
282
283M4OSA_Int32 VideoEditorBGAudioProcessing:: getDecibelSound(M4OSA_UInt32 value) {
284
285 int dbSound = 1;
286
287 if (value == 0) return 0;
288
289 if (value > 0x4000 && value <= 0x8000) // 32768
290 dbSound = 90;
291 else if (value > 0x2000 && value <= 0x4000) // 16384
292 dbSound = 84;
293 else if (value > 0x1000 && value <= 0x2000) // 8192
294 dbSound = 78;
295 else if (value > 0x0800 && value <= 0x1000) // 4028
296 dbSound = 72;
297 else if (value > 0x0400 && value <= 0x0800) // 2048
298 dbSound = 66;
299 else if (value > 0x0200 && value <= 0x0400) // 1024
300 dbSound = 60;
301 else if (value > 0x0100 && value <= 0x0200) // 512
302 dbSound = 54;
303 else if (value > 0x0080 && value <= 0x0100) // 256
304 dbSound = 48;
305 else if (value > 0x0040 && value <= 0x0080) // 128
306 dbSound = 42;
307 else if (value > 0x0020 && value <= 0x0040) // 64
308 dbSound = 36;
309 else if (value > 0x0010 && value <= 0x0020) // 32
310 dbSound = 30;
311 else if (value > 0x0008 && value <= 0x0010) //16
312 dbSound = 24;
313 else if (value > 0x0007 && value <= 0x0008) //8
314 dbSound = 24;
315 else if (value > 0x0003 && value <= 0x0007) // 4
316 dbSound = 18;
317 else if (value > 0x0001 && value <= 0x0003) //2
318 dbSound = 12;
319 else if (value > 0x000 && value <= 0x0001) // 1
320 dbSound = 6;
321 else
322 dbSound = 0;
323
324 return dbSound;
325}
326
327M4OSA_Bool VideoEditorBGAudioProcessing:: isThresholdBreached(
328 M4OSA_Int32* averageValue, M4OSA_Int32 storeCount,
329 M4OSA_Int32 thresholdValue) {
330
331 M4OSA_Bool result = 0;
332 int i;
333 int finalValue = 0;
334
335 for (i=0; i< storeCount;i++)
336 finalValue += averageValue[i];
337
338 finalValue = finalValue/storeCount;
339
340 //printf ("<%d > \t ", finalValue);
341
342 if (finalValue > thresholdValue)
343 result = M4OSA_TRUE;
344 else
345 result = M4OSA_FALSE;
346
347 return result;
348}
349
350}//namespace android