Dharmaray Kundargi | 643290d | 2011-01-16 16:02:42 -0800 | [diff] [blame] | 1 | /*
|
| 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 |
|
| 23 | namespace android {
|
| 24 |
|
| 25 | VideoEditorBGAudioProcessing ::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 |
|
| 50 | M4OSA_Int32 VideoEditorBGAudioProcessing::veProcessAudioMixNDuck(
|
| 51 | void *pPTBuffer, void *pBTBuffer, void *pOutBuffer) {
|
| 52 |
|
Rajneesh Chowdury | 1c97d9a | 2011-02-21 15:43:33 -0800 | [diff] [blame] | 53 | M4AM_Buffer16* pPrimaryTrack = (M4AM_Buffer16*)pPTBuffer;
|
| 54 | M4AM_Buffer16* pBackgroundTrack = (M4AM_Buffer16*)pBTBuffer;
|
| 55 | M4AM_Buffer16* pMixedOutBuffer = (M4AM_Buffer16*)pOutBuffer;
|
Dharmaray Kundargi | 643290d | 2011-01-16 16:02:42 -0800 | [diff] [blame] | 56 |
|
| 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 |
|
| 221 | VideoEditorBGAudioProcessing:: ~VideoEditorBGAudioProcessing() {
|
| 222 |
|
| 223 | //free(VideoEditorBGAudioProcessing:: pTempBuffer);
|
| 224 | }
|
| 225 |
|
| 226 | M4OSA_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 |
|
| 236 | void 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 |
|
| 283 | M4OSA_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 |
|
| 327 | M4OSA_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
|