VideoEditorAudioPlayer.cpp revision 643290dc4c83da23b1b8ff4ed71118203274bb15
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 "VideoEditorAudioPlayer" 20#include <utils/Log.h> 21 22#include <binder/IPCThreadState.h> 23#include <media/AudioTrack.h> 24#include <VideoEditorAudioPlayer.h> 25#include <media/stagefright/MediaDebug.h> 26#include <media/stagefright/MediaDefs.h> 27#include <media/stagefright/MediaErrors.h> 28#include <media/stagefright/MediaSource.h> 29#include <media/stagefright/MetaData.h> 30 31#include "PreviewPlayer.h" 32namespace android { 33 34VideoEditorAudioPlayer::VideoEditorAudioPlayer( 35 const sp<MediaPlayerBase::AudioSink> &audioSink, 36 AwesomePlayer *observer) 37 : AudioPlayer(audioSink, observer) { 38 39 LOGV("VideoEditorAudioPlayer"); 40 mBGAudioPCMFileHandle = NULL; 41 mBGAudioPCMFileLength = 0; 42 mBGAudioPCMFileTrimmedLength = 0; 43 mBGAudioPCMFileDuration = 0; 44 mBGAudioPCMFileSeekPoint = 0; 45 mBGAudioPCMFileOriginalSeekPoint = 0; 46 mBGAudioStoryBoardSkimTimeStamp = 0; 47 mBGAudioStoryBoardCurrentMediaBeginCutTS = 0; 48 mBGAudioStoryBoardCurrentMediaVolumeVal = 0; 49 mSeekTimeUs = 0; 50} 51 52VideoEditorAudioPlayer::~VideoEditorAudioPlayer() { 53 54 LOGV("~VideoEditorAudioPlayer"); 55 if (mStarted) { 56 reset(); 57 } 58} 59 60status_t VideoEditorAudioPlayer::start(bool sourceAlreadyStarted) { 61 62 CHECK(!mStarted); 63 CHECK(mSource != NULL); 64 LOGV("Start"); 65 status_t err; 66 M4OSA_ERR result = M4NO_ERROR; 67 M4OSA_UInt32 startTime = 0; 68 M4OSA_UInt32 seekTimeStamp = 0; 69 M4OSA_Bool bStoryBoardTSBeyondBTEndCutTime = M4OSA_FALSE; 70 71 if (!sourceAlreadyStarted) { 72 err = mSource->start(); 73 if (err != OK) { 74 return err; 75 } 76 } 77 78 // Create the BG Audio handler 79 mAudioProcess = new VideoEditorBGAudioProcessing(); 80 veAudMixSettings audioMixSettings; 81 82 // Pass on the audio ducking parameters 83 audioMixSettings.lvInDucking_threshold = mAudioMixSettings->uiInDucking_threshold; 84 audioMixSettings.lvInDucking_lowVolume = ((M4OSA_Float)mAudioMixSettings->uiInDucking_lowVolume) / 100.0; 85 audioMixSettings.lvInDucking_enable = mAudioMixSettings->bInDucking_enable; 86 audioMixSettings.lvPTVolLevel = ((M4OSA_Float)mBGAudioStoryBoardCurrentMediaVolumeVal) / 100.0; 87 audioMixSettings.lvBTVolLevel = ((M4OSA_Float)mAudioMixSettings->uiAddVolume) /100.0; 88 audioMixSettings.lvBTChannelCount = mAudioMixSettings->uiBTChannelCount; 89 audioMixSettings.lvPTChannelCount = mAudioMixSettings->uiNbChannels; 90 91 // Call to Audio mix param setting 92 mAudioProcess->veSetAudioProcessingParams(audioMixSettings); 93 94 // Get the BG Audio PCM file details 95 if ( mBGAudioPCMFileHandle ) { 96 97 // TODO : 32bits required for OSAL, to be updated once OSAL is updated 98 M4OSA_UInt32 tmp32 = 0; 99 result = M4OSA_fileReadGetOption(mBGAudioPCMFileHandle, 100 M4OSA_kFileReadGetFileSize, 101 (M4OSA_Void**)&tmp32); 102 mBGAudioPCMFileLength = tmp32; 103 mBGAudioPCMFileTrimmedLength = mBGAudioPCMFileLength; 104 105 106 LOGV("VideoEditorAudioPlayer::start M4OSA_kFileReadGetFileSize = %lld", 107 mBGAudioPCMFileLength); 108 109 // Get the duration in time of the audio BT 110 if ( result == M4NO_ERROR ) { 111 LOGV("VEAP: channels = %d freq = %d", 112 mAudioMixSettings->uiNbChannels, mAudioMixSettings->uiSamplingFrequency); 113 114 // No trim 115 mBGAudioPCMFileDuration = (( 116 (int64_t)(mBGAudioPCMFileLength/sizeof(M4OSA_UInt16)/ 117 mAudioMixSettings->uiNbChannels))*1000 ) / 118 mAudioMixSettings->uiSamplingFrequency; 119 120 LOGV("VideoEditorAudioPlayer:: beginCutMs %d , endCutMs %d", 121 (unsigned int) mAudioMixSettings->beginCutMs, 122 (unsigned int) mAudioMixSettings->endCutMs); 123 124 // Remove the trim part 125 if ((mAudioMixSettings->beginCutMs == 0) && 126 (mAudioMixSettings->endCutMs != 0)) { 127 // End time itself the file duration 128 mBGAudioPCMFileDuration = mAudioMixSettings->endCutMs; 129 // Limit the file length also 130 mBGAudioPCMFileTrimmedLength = (( 131 (int64_t)(mBGAudioPCMFileDuration * 132 mAudioMixSettings->uiSamplingFrequency) * 133 mAudioMixSettings->uiNbChannels) * 134 sizeof(M4OSA_UInt16)) / 1000; 135 } 136 else if ((mAudioMixSettings->beginCutMs != 0) && 137 (mAudioMixSettings->endCutMs == mBGAudioPCMFileDuration)) { 138 // End time itself the file duration 139 mBGAudioPCMFileDuration = mBGAudioPCMFileDuration - 140 mAudioMixSettings->beginCutMs; 141 // Limit the file length also 142 mBGAudioPCMFileTrimmedLength = (( 143 (int64_t)(mBGAudioPCMFileDuration * 144 mAudioMixSettings->uiSamplingFrequency) * 145 mAudioMixSettings->uiNbChannels) * 146 sizeof(M4OSA_UInt16)) / 1000; 147 } 148 else if ((mAudioMixSettings->beginCutMs != 0) && 149 (mAudioMixSettings->endCutMs != 0)) { 150 // End time itself the file duration 151 mBGAudioPCMFileDuration = mAudioMixSettings->endCutMs - 152 mAudioMixSettings->beginCutMs; 153 // Limit the file length also 154 mBGAudioPCMFileTrimmedLength = (( 155 (int64_t)(mBGAudioPCMFileDuration * 156 mAudioMixSettings->uiSamplingFrequency) * 157 mAudioMixSettings->uiNbChannels) * 158 sizeof(M4OSA_UInt16)) / 1000; /*make to sec from ms*/ 159 } 160 161 LOGV("VideoEditorAudioPlayer: file duration recorded : %lld", 162 mBGAudioPCMFileDuration); 163 } 164 165 // Last played location to be seeked at for next media item 166 if ( result == M4NO_ERROR ) { 167 LOGV("VideoEditorAudioPlayer::mBGAudioStoryBoardSkimTimeStamp %lld", 168 mBGAudioStoryBoardSkimTimeStamp); 169 LOGV("VideoEditorAudioPlayer::uiAddCts %d", 170 mAudioMixSettings->uiAddCts); 171 if (mBGAudioStoryBoardSkimTimeStamp >= mAudioMixSettings->uiAddCts) { 172 startTime = (mBGAudioStoryBoardSkimTimeStamp - 173 mAudioMixSettings->uiAddCts); 174 } 175 else { 176 // do nothing 177 } 178 179 LOGV("VideoEditorAudioPlayer::startTime %d", startTime); 180 seekTimeStamp = 0; 181 if (startTime) { 182 if (startTime >= mBGAudioPCMFileDuration) { 183 // The BG track should be looped and started again 184 if (mAudioMixSettings->bLoop) { 185 // Add begin cut time to the mod value 186 seekTimeStamp = ((startTime%mBGAudioPCMFileDuration) + 187 mAudioMixSettings->beginCutMs); 188 }else { 189 // Looping disabled, donot do BT Mix , set to file end 190 seekTimeStamp = (mBGAudioPCMFileDuration + 191 mAudioMixSettings->beginCutMs); 192 } 193 }else { 194 // BT still present , just seek to story board time 195 seekTimeStamp = startTime + mAudioMixSettings->beginCutMs; 196 } 197 } 198 else { 199 seekTimeStamp = mAudioMixSettings->beginCutMs; 200 } 201 202 // Convert the seekTimeStamp to file location 203 mBGAudioPCMFileOriginalSeekPoint = ( 204 (int64_t)(mAudioMixSettings->beginCutMs) 205 * mAudioMixSettings->uiSamplingFrequency 206 * mAudioMixSettings->uiNbChannels 207 * sizeof(M4OSA_UInt16))/ 1000 ; /*make to sec from ms*/ 208 209 mBGAudioPCMFileSeekPoint = ((int64_t)(seekTimeStamp) 210 * mAudioMixSettings->uiSamplingFrequency 211 * mAudioMixSettings->uiNbChannels 212 * sizeof(M4OSA_UInt16))/ 1000 ; 213 } 214 } 215 216 // We allow an optional INFO_FORMAT_CHANGED at the very beginning 217 // of playback, if there is one, getFormat below will retrieve the 218 // updated format, if there isn't, we'll stash away the valid buffer 219 // of data to be used on the first audio callback. 220 221 CHECK(mFirstBuffer == NULL); 222 223 mFirstBufferResult = mSource->read(&mFirstBuffer); 224 if (mFirstBufferResult == INFO_FORMAT_CHANGED) { 225 LOGV("INFO_FORMAT_CHANGED!!!"); 226 227 CHECK(mFirstBuffer == NULL); 228 mFirstBufferResult = OK; 229 mIsFirstBuffer = false; 230 } else { 231 mIsFirstBuffer = true; 232 } 233 234 sp<MetaData> format = mSource->getFormat(); 235 const char *mime; 236 bool success = format->findCString(kKeyMIMEType, &mime); 237 CHECK(success); 238 CHECK(!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW)); 239 240 success = format->findInt32(kKeySampleRate, &mSampleRate); 241 CHECK(success); 242 243 int32_t numChannels; 244 success = format->findInt32(kKeyChannelCount, &numChannels); 245 CHECK(success); 246 247 if (mAudioSink.get() != NULL) { 248 status_t err = mAudioSink->open( 249 mSampleRate, numChannels, AudioSystem::PCM_16_BIT, 250 DEFAULT_AUDIOSINK_BUFFERCOUNT, 251 &VideoEditorAudioPlayer::AudioSinkCallback, this); 252 if (err != OK) { 253 if (mFirstBuffer != NULL) { 254 mFirstBuffer->release(); 255 mFirstBuffer = NULL; 256 } 257 258 if (!sourceAlreadyStarted) { 259 mSource->stop(); 260 } 261 262 return err; 263 } 264 265 mLatencyUs = (int64_t)mAudioSink->latency() * 1000; 266 mFrameSize = mAudioSink->frameSize(); 267 268 mAudioSink->start(); 269 } else { 270 mAudioTrack = new AudioTrack( 271 AudioSystem::MUSIC, mSampleRate, AudioSystem::PCM_16_BIT, 272 (numChannels == 2) 273 ? AudioSystem::CHANNEL_OUT_STEREO 274 : AudioSystem::CHANNEL_OUT_MONO, 275 0, 0, &AudioCallback, this, 0); 276 277 if ((err = mAudioTrack->initCheck()) != OK) { 278 delete mAudioTrack; 279 mAudioTrack = NULL; 280 281 if (mFirstBuffer != NULL) { 282 mFirstBuffer->release(); 283 mFirstBuffer = NULL; 284 } 285 286 if (!sourceAlreadyStarted) { 287 mSource->stop(); 288 } 289 290 return err; 291 } 292 293 mLatencyUs = (int64_t)mAudioTrack->latency() * 1000; 294 mFrameSize = mAudioTrack->frameSize(); 295 296 mAudioTrack->start(); 297 } 298 299 mStarted = true; 300 301 return OK; 302} 303 304void VideoEditorAudioPlayer::reset() { 305 306 LOGV("reset"); 307 AudioPlayer::reset(); 308 309 // Capture the current seek point 310 mBGAudioPCMFileSeekPoint = 0; 311 mBGAudioStoryBoardSkimTimeStamp =0; 312 mBGAudioStoryBoardCurrentMediaBeginCutTS=0; 313} 314 315size_t VideoEditorAudioPlayer::AudioSinkCallback( 316 MediaPlayerBase::AudioSink *audioSink, 317 void *buffer, size_t size, void *cookie) { 318 VideoEditorAudioPlayer *me = (VideoEditorAudioPlayer *)cookie; 319 320 return me->fillBuffer(buffer, size); 321} 322 323 324size_t VideoEditorAudioPlayer::fillBuffer(void *data, size_t size) { 325 326 if (mReachedEOS) { 327 return 0; 328 } 329 330 size_t size_done = 0; 331 size_t size_remaining = size; 332 333 M4OSA_ERR err = M4NO_ERROR; 334 M4AM_Buffer bgFrame = {NULL, 0}; 335 M4AM_Buffer mixFrame = {NULL, 0}; 336 M4AM_Buffer ptFrame = {NULL, 0}; 337 int64_t currentSteamTS = 0; 338 int64_t startTimeForBT = 0; 339 M4OSA_Float fPTVolLevel = 340 ((M4OSA_Float)mBGAudioStoryBoardCurrentMediaVolumeVal)/100; 341 M4OSA_Int16 *pPTMdata; 342 M4OSA_UInt32 uiPCMsize = 0; 343 344 while ((size_remaining > 0)&&(err==M4NO_ERROR)) { 345 MediaSource::ReadOptions options; 346 347 { 348 Mutex::Autolock autoLock(mLock); 349 if (mSeeking) { 350 if (mIsFirstBuffer) { 351 if (mFirstBuffer != NULL) { 352 mFirstBuffer->release(); 353 mFirstBuffer = NULL; 354 } 355 mIsFirstBuffer = false; 356 } 357 358 options.setSeekTo(mSeekTimeUs); 359 360 if (mInputBuffer != NULL) { 361 mInputBuffer->release(); 362 mInputBuffer = NULL; 363 } 364 365 mSeeking = false; 366 if (mObserver) { 367 mObserver->postAudioSeekComplete(); 368 } 369 } 370 } 371 372 if (mInputBuffer == NULL) { 373 status_t status = OK; 374 375 if (mIsFirstBuffer) { 376 mInputBuffer = mFirstBuffer; 377 mFirstBuffer = NULL; 378 status = mFirstBufferResult; 379 380 mIsFirstBuffer = false; 381 } else { 382 status = mSource->read(&mInputBuffer, &options); 383 // Data is Primary Track, mix with background track 384 // after reading same size from Background track PCM file 385 if (status == OK) 386 { 387 // Mix only when skim point is after startTime of BT 388 if (((mBGAudioStoryBoardSkimTimeStamp* 1000) + 389 (mPositionTimeMediaUs - mSeekTimeUs)) >= 390 (int64_t)(mAudioMixSettings->uiAddCts * 1000)) { 391 392 LOGV("VideoEditorAudioPlayer::INSIDE MIXING"); 393 LOGV("Checking %lld <= %lld - %d", 394 mBGAudioPCMFileSeekPoint-mBGAudioPCMFileOriginalSeekPoint, 395 mBGAudioPCMFileTrimmedLength, len); 396 397 398 M4OSA_Void* ptr; 399 ptr = (M4OSA_Void*)((unsigned int)mInputBuffer->data() + 400 mInputBuffer->range_offset()); 401 402 M4OSA_UInt32 len = mInputBuffer->range_length(); 403 M4OSA_Context fp = M4OSA_NULL; 404 405 uiPCMsize = (mInputBuffer->range_length())/2; 406 pPTMdata = (M4OSA_Int16*)(mInputBuffer->data() + 407 mInputBuffer->range_offset()); 408 409 LOGV("mix with background malloc to do len %d", len); 410 411 bgFrame.m_dataAddress = (M4OSA_UInt16*)M4OSA_malloc( len, 1, 412 (M4OSA_Char*)"bgFrame"); 413 if (NULL == bgFrame.m_dataAddress) { 414 LOGE("mBackgroundAudioSetting Malloc failed"); 415 } 416 417 bgFrame.m_bufferSize = len; 418 419 mixFrame.m_dataAddress = (M4OSA_UInt16*)M4OSA_malloc(len, 1, 420 (M4OSA_Char*)"mixFrame"); 421 if (NULL == mixFrame.m_dataAddress) { 422 LOGE("mBackgroundAudioSetting Malloc failed"); 423 } 424 425 mixFrame.m_bufferSize = len; 426 427 LOGV("mix with bgm with size %lld", mBGAudioPCMFileLength); 428 429 CHECK(mInputBuffer->meta_data()->findInt64(kKeyTime, 430 &mPositionTimeMediaUs)); 431 432 if (mBGAudioPCMFileSeekPoint - 433 mBGAudioPCMFileOriginalSeekPoint <= 434 (mBGAudioPCMFileTrimmedLength - len)) { 435 436 LOGV("Checking mBGAudioPCMFileHandle %d", 437 (unsigned int)mBGAudioPCMFileHandle); 438 439 if (mBGAudioPCMFileHandle != M4OSA_NULL) { 440 LOGV("fillBuffer seeking file to %lld", 441 mBGAudioPCMFileSeekPoint); 442 443 // TODO : 32bits required for OSAL 444 M4OSA_UInt32 tmp32 = 445 (M4OSA_UInt32)mBGAudioPCMFileSeekPoint; 446 err = M4OSA_fileReadSeek(mBGAudioPCMFileHandle, 447 M4OSA_kFileSeekBeginning, 448 (M4OSA_FilePosition*)&tmp32); 449 450 mBGAudioPCMFileSeekPoint = tmp32; 451 452 if (err != M4NO_ERROR){ 453 LOGE("M4OSA_fileReadSeek err %d", err); 454 } 455 456 err = M4OSA_fileReadData(mBGAudioPCMFileHandle, 457 (M4OSA_Int8*)bgFrame.m_dataAddress, 458 (M4OSA_UInt32*)&len); 459 if (err == M4WAR_NO_DATA_YET ) { 460 461 LOGV("fillBuffer End of file reached"); 462 err = M4NO_ERROR; 463 464 // We reached the end of file 465 // move to begin cut time equal value 466 if (mAudioMixSettings->bLoop) { 467 mBGAudioPCMFileSeekPoint = 468 (((int64_t)(mAudioMixSettings->beginCutMs) * 469 mAudioMixSettings->uiSamplingFrequency) * 470 mAudioMixSettings->uiNbChannels * 471 sizeof(M4OSA_UInt16)) / 1000; 472 LOGV("fillBuffer Looping \ 473 to mBGAudioPCMFileSeekPoint %lld", 474 mBGAudioPCMFileSeekPoint); 475 } 476 else { 477 // No mixing; 478 // take care of volume of primary track 479 if (fPTVolLevel < 1.0) { 480 setPrimaryTrackVolume(pPTMdata, 481 uiPCMsize, fPTVolLevel); 482 } 483 } 484 } else if (err != M4NO_ERROR ) { 485 LOGV("fileReadData for audio err %d", err); 486 } else { 487 mBGAudioPCMFileSeekPoint += len; 488 LOGV("fillBuffer mBGAudioPCMFileSeekPoint \ 489 %lld", mBGAudioPCMFileSeekPoint); 490 491 // Assign the ptr data to primary track 492 ptFrame.m_dataAddress = (M4OSA_UInt16*)ptr; 493 ptFrame.m_bufferSize = len; 494 495 // Call to mix and duck 496 mAudioProcess->veProcessAudioMixNDuck( 497 &ptFrame, &bgFrame, &mixFrame); 498 499 // Overwrite the decoded buffer 500 M4OSA_memcpy((M4OSA_MemAddr8)ptr, 501 (M4OSA_MemAddr8)mixFrame.m_dataAddress, len); 502 } 503 } 504 } else if (mAudioMixSettings->bLoop){ 505 // Move to begin cut time equal value 506 mBGAudioPCMFileSeekPoint = 507 mBGAudioPCMFileOriginalSeekPoint; 508 } else { 509 // No mixing; 510 // take care of volume level of primary track 511 if(fPTVolLevel < 1.0) { 512 setPrimaryTrackVolume( 513 pPTMdata, uiPCMsize, fPTVolLevel); 514 } 515 } 516 if (bgFrame.m_dataAddress) { 517 M4OSA_free((M4OSA_MemAddr32)bgFrame.m_dataAddress); 518 } 519 if (mixFrame.m_dataAddress) { 520 M4OSA_free((M4OSA_MemAddr32)mixFrame.m_dataAddress); 521 } 522 } else { 523 // No mixing; 524 // take care of volume level of primary track 525 if(fPTVolLevel < 1.0) { 526 setPrimaryTrackVolume(pPTMdata, uiPCMsize, 527 fPTVolLevel); 528 } 529 } 530 } 531 } 532 533 CHECK((status == OK && mInputBuffer != NULL) 534 || (status != OK && mInputBuffer == NULL)); 535 536 Mutex::Autolock autoLock(mLock); 537 538 if (status != OK) { 539 LOGV("fillBuffer: mSource->read returned err %d", status); 540 if (mObserver && !mReachedEOS) { 541 mObserver->postAudioEOS(); 542 } 543 544 mReachedEOS = true; 545 mFinalStatus = status; 546 break; 547 } 548 549 CHECK(mInputBuffer->meta_data()->findInt64( 550 kKeyTime, &mPositionTimeMediaUs)); 551 552 mPositionTimeRealUs = 553 ((mNumFramesPlayed + size_done / mFrameSize) * 1000000) 554 / mSampleRate; 555 556 LOGV("buffer->size() = %d, " 557 "mPositionTimeMediaUs=%.2f mPositionTimeRealUs=%.2f", 558 mInputBuffer->range_length(), 559 mPositionTimeMediaUs / 1E6, mPositionTimeRealUs / 1E6); 560 } 561 562 if (mInputBuffer->range_length() == 0) { 563 mInputBuffer->release(); 564 mInputBuffer = NULL; 565 566 continue; 567 } 568 569 size_t copy = size_remaining; 570 if (copy > mInputBuffer->range_length()) { 571 copy = mInputBuffer->range_length(); 572 } 573 574 memcpy((char *)data + size_done, 575 (const char *)mInputBuffer->data() + mInputBuffer->range_offset(), 576 copy); 577 578 mInputBuffer->set_range(mInputBuffer->range_offset() + copy, 579 mInputBuffer->range_length() - copy); 580 581 size_done += copy; 582 size_remaining -= copy; 583 } 584 585 Mutex::Autolock autoLock(mLock); 586 mNumFramesPlayed += size_done / mFrameSize; 587 588 return size_done; 589} 590 591void VideoEditorAudioPlayer::setAudioMixSettings( 592 M4xVSS_AudioMixingSettings* pAudioMixSettings) { 593 mAudioMixSettings = pAudioMixSettings; 594} 595 596void VideoEditorAudioPlayer::setAudioMixPCMFileHandle( 597 M4OSA_Context pBGAudioPCMFileHandle){ 598 mBGAudioPCMFileHandle = pBGAudioPCMFileHandle; 599} 600 601void VideoEditorAudioPlayer::setAudioMixStoryBoardSkimTimeStamp( 602 M4OSA_UInt32 pBGAudioStoryBoardSkimTimeStamp, 603 M4OSA_UInt32 pBGAudioCurrentMediaBeginCutTS, 604 M4OSA_UInt32 pBGAudioCurrentMediaVolumeVal) { 605 606 mBGAudioStoryBoardSkimTimeStamp = pBGAudioStoryBoardSkimTimeStamp; 607 mBGAudioStoryBoardCurrentMediaBeginCutTS = pBGAudioCurrentMediaBeginCutTS; 608 mBGAudioStoryBoardCurrentMediaVolumeVal = pBGAudioCurrentMediaVolumeVal; 609} 610 611void VideoEditorAudioPlayer::setPrimaryTrackVolume( 612 M4OSA_Int16 *data, M4OSA_UInt32 size, M4OSA_Float volLevel) { 613 614 while(size-- > 0) { 615 *data = (M4OSA_Int16)((*data)*volLevel); 616 data++; 617 } 618} 619 620} 621