1 /* 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 0 18 #define LOG_TAG "VideoEditorBGAudioProcessing" 19 #include <utils/Log.h> 20 #include "VideoEditorBGAudioProcessing.h" 21 22 namespace android { 23 24 VideoEditorBGAudioProcessing::VideoEditorBGAudioProcessing() { 25 ALOGV("Constructor"); 26 27 mAudVolArrIndex = 0; 28 mDoDucking = 0; 29 mDucking_enable = 0; 30 mDucking_lowVolume = 0; 31 mDucking_threshold = 0; 32 mDuckingFactor = 0; 33 34 mBTVolLevel = 0; 35 mPTVolLevel = 0; 36 37 mIsSSRCneeded = 0; 38 mChannelConversion = 0; 39 40 mBTFormat = MONO_16_BIT; 41 42 mInSampleRate = 8000; 43 mOutSampleRate = 16000; 44 mPTChannelCount = 2; 45 mBTChannelCount = 1; 46 } 47 48 M4OSA_Int32 VideoEditorBGAudioProcessing::mixAndDuck( 49 void *primaryTrackBuffer, 50 void *backgroundTrackBuffer, 51 void *outBuffer) { 52 53 ALOGV("mixAndDuck: track buffers (primary: 0x%x and background: 0x%x) " 54 "and out buffer 0x%x", 55 primaryTrackBuffer, backgroundTrackBuffer, outBuffer); 56 57 M4AM_Buffer16* pPrimaryTrack = (M4AM_Buffer16*)primaryTrackBuffer; 58 M4AM_Buffer16* pBackgroundTrack = (M4AM_Buffer16*)backgroundTrackBuffer; 59 M4AM_Buffer16* pMixedOutBuffer = (M4AM_Buffer16*)outBuffer; 60 61 // Output size if same as PT size 62 pMixedOutBuffer->m_bufferSize = pPrimaryTrack->m_bufferSize; 63 64 // Before mixing, we need to have only PT as out buffer 65 memcpy((void *)pMixedOutBuffer->m_dataAddress, 66 (void *)pPrimaryTrack->m_dataAddress, pMixedOutBuffer->m_bufferSize); 67 68 // Initialize ducking variables 69 // Initially contains the input primary track 70 M4OSA_Int16 *pPTMdata2 = (M4OSA_Int16*)pMixedOutBuffer->m_dataAddress; 71 72 // Contains BG track processed data(like channel conversion etc.. 73 M4OSA_Int16 *pBTMdata1 = (M4OSA_Int16*) pBackgroundTrack->m_dataAddress; 74 75 // Since we need to give sample count and not buffer size 76 M4OSA_UInt32 uiPCMsize = pMixedOutBuffer->m_bufferSize / 2 ; 77 78 if ((mDucking_enable) && (mPTVolLevel != 0.0)) { 79 M4OSA_Int32 peakDbValue = 0; 80 M4OSA_Int32 previousDbValue = 0; 81 M4OSA_Int16 *pPCM16Sample = (M4OSA_Int16*)pPrimaryTrack->m_dataAddress; 82 const size_t n = pPrimaryTrack->m_bufferSize / sizeof(M4OSA_Int16); 83 84 for (size_t loopIndex = 0; loopIndex < n; ++loopIndex) { 85 if (pPCM16Sample[loopIndex] >= 0) { 86 peakDbValue = previousDbValue > pPCM16Sample[loopIndex] ? 87 previousDbValue : pPCM16Sample[loopIndex]; 88 previousDbValue = peakDbValue; 89 } else { 90 peakDbValue = previousDbValue > -pPCM16Sample[loopIndex] ? 91 previousDbValue: -pPCM16Sample[loopIndex]; 92 previousDbValue = peakDbValue; 93 } 94 } 95 96 mAudioVolumeArray[mAudVolArrIndex] = getDecibelSound(peakDbValue); 97 98 // Check for threshold is done after kProcessingWindowSize cycles 99 if (mAudVolArrIndex >= kProcessingWindowSize - 1) { 100 mDoDucking = isThresholdBreached( 101 mAudioVolumeArray, mAudVolArrIndex, mDucking_threshold); 102 103 mAudVolArrIndex = 0; 104 } else { 105 mAudVolArrIndex++; 106 } 107 108 // 109 // Below logic controls the mixing weightage 110 // for Background and Primary Tracks 111 // for the duration of window under analysis, 112 // to give fade-out for Background and fade-in for primary 113 // Current fading factor is distributed in equal range over 114 // the defined window size. 115 // For a window size = 25 116 // (500 ms (window under analysis) / 20 ms (sample duration)) 117 // 118 119 if (mDoDucking) { 120 if (mDuckingFactor > mDucking_lowVolume) { 121 // FADE OUT BG Track 122 // Increment ducking factor in total steps in factor 123 // of low volume steps to reach low volume level 124 mDuckingFactor -= mDucking_lowVolume; 125 } else { 126 mDuckingFactor = mDucking_lowVolume; 127 } 128 } else { 129 if (mDuckingFactor < 1.0 ) { 130 // FADE IN BG Track 131 // Increment ducking factor in total steps of 132 // low volume factor to reach orig.volume level 133 mDuckingFactor += mDucking_lowVolume; 134 } else { 135 mDuckingFactor = 1.0; 136 } 137 } 138 } // end if - mDucking_enable 139 140 141 // Mixing logic 142 ALOGV("Out of Ducking analysis uiPCMsize %d %f %f", 143 mDoDucking, mDuckingFactor, mBTVolLevel); 144 while (uiPCMsize-- > 0) { 145 146 // Set vol factor for BT and PT 147 *pBTMdata1 = (M4OSA_Int16)(*pBTMdata1*mBTVolLevel); 148 *pPTMdata2 = (M4OSA_Int16)(*pPTMdata2*mPTVolLevel); 149 150 // Mix the two samples 151 if (mDoDucking) { 152 153 // Duck the BG track to ducking factor value before mixing 154 *pBTMdata1 = (M4OSA_Int16)((*pBTMdata1)*(mDuckingFactor)); 155 156 // mix as normal case 157 *pBTMdata1 = (M4OSA_Int16)(*pBTMdata1 /2 + *pPTMdata2 /2); 158 } else { 159 160 *pBTMdata1 = (M4OSA_Int16)((*pBTMdata1)*(mDuckingFactor)); 161 *pBTMdata1 = (M4OSA_Int16)(*pBTMdata1 /2 + *pPTMdata2 /2); 162 } 163 164 M4OSA_Int32 temp; 165 if (*pBTMdata1 < 0) { 166 temp = -(*pBTMdata1) * 2; // bring to original Amplitude level 167 168 if (temp > 32767) { 169 *pBTMdata1 = -32766; // less then max allowed value 170 } else { 171 *pBTMdata1 = (M4OSA_Int16)(-temp); 172 } 173 } else { 174 temp = (*pBTMdata1) * 2; // bring to original Amplitude level 175 if ( temp > 32768) { 176 *pBTMdata1 = 32767; // less than max allowed value 177 } else { 178 *pBTMdata1 = (M4OSA_Int16)temp; 179 } 180 } 181 182 pBTMdata1++; 183 pPTMdata2++; 184 } 185 186 memcpy((void *)pMixedOutBuffer->m_dataAddress, 187 (void *)pBackgroundTrack->m_dataAddress, 188 pBackgroundTrack->m_bufferSize); 189 190 ALOGV("mixAndDuck: X"); 191 return M4NO_ERROR; 192 } 193 194 M4OSA_Int32 VideoEditorBGAudioProcessing::calculateOutResampleBufSize() { 195 196 // This already takes care of channel count in mBTBuffer.m_bufferSize 197 return (mOutSampleRate / mInSampleRate) * mBTBuffer.m_bufferSize; 198 } 199 200 void VideoEditorBGAudioProcessing::setMixParams( 201 const AudioMixSettings& setting) { 202 ALOGV("setMixParams"); 203 204 mDucking_enable = setting.lvInDucking_enable; 205 mDucking_lowVolume = setting.lvInDucking_lowVolume; 206 mDucking_threshold = setting.lvInDucking_threshold; 207 mPTVolLevel = setting.lvPTVolLevel; 208 mBTVolLevel = setting.lvBTVolLevel ; 209 mBTChannelCount = setting.lvBTChannelCount; 210 mPTChannelCount = setting.lvPTChannelCount; 211 mBTFormat = setting.lvBTFormat; 212 mInSampleRate = setting.lvInSampleRate; 213 mOutSampleRate = setting.lvOutSampleRate; 214 215 // Reset the following params to default values 216 mAudVolArrIndex = 0; 217 mDoDucking = 0; 218 mDuckingFactor = 1.0; 219 220 ALOGV("ducking enable 0x%x lowVolume %f threshold %d " 221 "fPTVolLevel %f BTVolLevel %f", 222 mDucking_enable, mDucking_lowVolume, mDucking_threshold, 223 mPTVolLevel, mPTVolLevel); 224 225 // Decides if SSRC support is needed for this mixing 226 mIsSSRCneeded = (setting.lvInSampleRate != setting.lvOutSampleRate); 227 if (setting.lvBTChannelCount != setting.lvPTChannelCount){ 228 if (setting.lvBTChannelCount == 2){ 229 mChannelConversion = 1; // convert to MONO 230 } else { 231 mChannelConversion = 2; // Convert to STEREO 232 } 233 } else { 234 mChannelConversion = 0; 235 } 236 } 237 238 // Fast way to compute 10 * log(value) 239 M4OSA_Int32 VideoEditorBGAudioProcessing::getDecibelSound(M4OSA_UInt32 value) { 240 ALOGV("getDecibelSound: %ld", value); 241 242 if (value <= 0 || value > 0x8000) { 243 return 0; 244 } else if (value > 0x4000) { // 32768 245 return 90; 246 } else if (value > 0x2000) { // 16384 247 return 84; 248 } else if (value > 0x1000) { // 8192 249 return 78; 250 } else if (value > 0x0800) { // 4028 251 return 72; 252 } else if (value > 0x0400) { // 2048 253 return 66; 254 } else if (value > 0x0200) { // 1024 255 return 60; 256 } else if (value > 0x0100) { // 512 257 return 54; 258 } else if (value > 0x0080) { // 256 259 return 48; 260 } else if (value > 0x0040) { // 128 261 return 42; 262 } else if (value > 0x0020) { // 64 263 return 36; 264 } else if (value > 0x0010) { // 32 265 return 30; 266 } else if (value > 0x0008) { // 16 267 return 24; 268 } else if (value > 0x0007) { // 8 269 return 24; 270 } else if (value > 0x0003) { // 4 271 return 18; 272 } else if (value > 0x0001) { // 2 273 return 12; 274 } else { // 1 275 return 6; 276 } 277 } 278 279 M4OSA_Bool VideoEditorBGAudioProcessing::isThresholdBreached( 280 M4OSA_Int32* averageValue, 281 M4OSA_Int32 storeCount, 282 M4OSA_Int32 thresholdValue) { 283 284 ALOGV("isThresholdBreached"); 285 286 int totalValue = 0; 287 for (int i = 0; i < storeCount; ++i) { 288 totalValue += averageValue[i]; 289 } 290 return (totalValue / storeCount > thresholdValue); 291 } 292 293 }//namespace android 294