00001
00033 #include "linden_common.h"
00034
00035 #include "audioengine.h"
00036
00037 #include "llerror.h"
00038 #include "llmath.h"
00039
00040 #include "sound_ids.h"
00041
00042 #include "llvfs.h"
00043 #include "lldir.h"
00044 #include "llaudiodecodemgr.h"
00045 #include "llassetstorage.h"
00046
00047
00048 extern void request_sound(const LLUUID &sound_guid);
00049
00050 LLAudioEngine* gAudiop = NULL;
00051
00052
00053
00054 const F32 MAX_CURRENT_TRANSFER_TIME = 60.f;
00055
00056
00057
00058
00059
00060
00061 LLAudioEngine::LLAudioEngine()
00062 {
00063 }
00064
00065
00066 LLAudioEngine::~LLAudioEngine()
00067 {
00068 }
00069
00070
00071 BOOL LLAudioEngine::init(const S32 num_channels, void* userdata)
00072 {
00073 mMuted = FALSE;
00074 mMasterGain = 1.f;
00075 mInternetStreamGain = 0.125f;
00076 mUserData = userdata;
00077 mLastStatus = 0;
00078
00079 mNumChannels = num_channels;
00080
00081
00082 mMaxWindGain = 1.0;
00083
00084 mEnableWind = FALSE;
00085
00086 S32 i;
00087 for (i = 0; i < MAX_BUFFERS; i++)
00088 {
00089 mBuffers[i] = NULL;
00090 }
00091 for (i = 0; i < num_channels; i++)
00092 {
00093 mChannels[i] = NULL;
00094 }
00095
00096 allocateListener();
00097
00098
00099 gAudioDecodeMgrp = new LLAudioDecodeMgr;
00100
00101 return TRUE;
00102 }
00103
00104
00105 void LLAudioEngine::shutdown()
00106 {
00107
00108 delete gAudioDecodeMgrp;
00109 gAudioDecodeMgrp = NULL;
00110
00111
00112 source_map::iterator iter_src;
00113 for (iter_src = mAllSources.begin(); iter_src != mAllSources.end(); iter_src++)
00114 {
00115 delete iter_src->second;
00116 }
00117
00118
00119
00120 data_map::iterator iter_data;
00121 for (iter_data = mAllData.begin(); iter_data != mAllData.end(); iter_data++)
00122 {
00123 delete iter_data->second;
00124 }
00125
00126
00127
00128 S32 i;
00129 for (i = 0; i < MAX_CHANNELS; i++)
00130 {
00131 if (mChannels[i])
00132 {
00133 delete mChannels[i];
00134 mChannels[i] = NULL;
00135 }
00136 }
00137
00138
00139 for (i = 0; i < MAX_BUFFERS; i++)
00140 {
00141 if (mBuffers[i])
00142 {
00143 delete mBuffers[i];
00144 mBuffers[i] = NULL;
00145 }
00146 }
00147 }
00148
00149
00150 void LLAudioEngine::updateChannels()
00151 {
00152 S32 i;
00153 for (i = 0; i < MAX_CHANNELS; i++)
00154 {
00155 if (mChannels[i])
00156 {
00157 mChannels[i]->updateBuffer();
00158 mChannels[i]->update3DPosition();
00159 mChannels[i]->updateLoop();
00160 }
00161 }
00162 }
00163
00164 static const F32 default_max_decode_time = .002f;
00165 void LLAudioEngine::idle(F32 max_decode_time)
00166 {
00167 if (max_decode_time <= 0.f)
00168 {
00169 max_decode_time = default_max_decode_time;
00170 }
00171
00172
00173
00174
00175
00176 if (getMuted())
00177 {
00178 setInternalGain(0.f);
00179 }
00180 else
00181 {
00182 setInternalGain(getMasterGain());
00183 }
00184
00185 S32 i;
00186 for (i = 0; i < MAX_BUFFERS; i++)
00187 {
00188 if (mBuffers[i])
00189 {
00190 mBuffers[i]->mInUse = FALSE;
00191 }
00192 }
00193
00194 F32 max_priority = -1.f;
00195 LLAudioSource *max_sourcep = NULL;
00196 source_map::iterator iter;
00197 for (iter = mAllSources.begin(); iter != mAllSources.end();)
00198 {
00199 LLAudioSource *sourcep = iter->second;
00200
00201
00202 sourcep->update();
00203 sourcep->updatePriority();
00204
00205 if (sourcep->isDone())
00206 {
00207
00208 delete sourcep;
00209 mAllSources.erase(iter++);
00210 continue;
00211 }
00212
00213 if (!sourcep->getChannel() && sourcep->getCurrentBuffer())
00214 {
00215
00216 if (sourcep->getPriority() > max_priority)
00217 {
00218 max_priority = sourcep->getPriority();
00219 max_sourcep = sourcep;
00220 }
00221 }
00222
00223
00224 iter++;
00225 }
00226
00227
00228
00229
00230 if (max_sourcep)
00231 {
00232 LLAudioChannel *channelp = getFreeChannel(max_priority);
00233 if (channelp)
00234 {
00235
00236 max_sourcep->setChannel(channelp);
00237 channelp->setSource(max_sourcep);
00238 if (max_sourcep->isSyncSlave())
00239 {
00240
00241
00242 channelp->setWaiting(TRUE);
00243 }
00244 else
00245 {
00246 channelp->setWaiting(FALSE);
00247 channelp->play();
00248 }
00249 }
00250 }
00251
00252
00253
00254
00255
00256 updateChannels();
00257
00258
00259 for (iter = mAllSources.begin(); iter != mAllSources.end(); ++iter)
00260 {
00261
00262
00263
00264 LLAudioSource *sourcep = iter->second;
00265 if (!sourcep->mQueuedDatap)
00266 {
00267
00268 continue;
00269 }
00270
00271 LLAudioChannel *channelp = sourcep->getChannel();
00272 if (!channelp)
00273 {
00274
00275 sourcep->mCurrentDatap = sourcep->mQueuedDatap;
00276 sourcep->mQueuedDatap = NULL;
00277
00278
00279 sourcep->mAgeTimer.reset();
00280
00281 if (sourcep->mCurrentDatap)
00282 {
00283 updateBufferForData(sourcep->mCurrentDatap);
00284 }
00285
00286
00287 sourcep->setupChannel();
00288 channelp = sourcep->getChannel();
00289 if (channelp)
00290 {
00291 channelp->updateBuffer();
00292 sourcep->getChannel()->play();
00293 }
00294 continue;
00295 }
00296 else
00297 {
00298
00299 if (!channelp->isPlaying())
00300 {
00301 sourcep->mCurrentDatap = sourcep->mQueuedDatap;
00302 sourcep->mQueuedDatap = NULL;
00303
00304
00305 sourcep->mAgeTimer.reset();
00306
00307
00308 if (sourcep->mCurrentDatap)
00309 {
00310 updateBufferForData(sourcep->mCurrentDatap);
00311 }
00312
00313
00314 sourcep->setupChannel();
00315 channelp->updateBuffer();
00316 sourcep->getChannel()->play();
00317 }
00318 else if (sourcep->isLoop())
00319 {
00320
00321 if (channelp->mLoopedThisFrame)
00322 {
00323 sourcep->mCurrentDatap = sourcep->mQueuedDatap;
00324 sourcep->mQueuedDatap = NULL;
00325
00326
00327
00328 sourcep->setupChannel();
00329 sourcep->getChannel()->play();
00330 }
00331 }
00332 }
00333 }
00334
00335
00336
00337
00338 updateChannels();
00339
00340
00341 LLAudioSource *sync_masterp = NULL;
00342 LLAudioChannel *master_channelp = NULL;
00343 F32 max_sm_priority = -1.f;
00344 for (iter = mAllSources.begin(); iter != mAllSources.end(); ++iter)
00345 {
00346 LLAudioSource *sourcep = iter->second;
00347 if (sourcep->isSyncMaster())
00348 {
00349 if (sourcep->getPriority() > max_sm_priority)
00350 {
00351 sync_masterp = sourcep;
00352 master_channelp = sync_masterp->getChannel();
00353 max_sm_priority = sourcep->getPriority();
00354 }
00355 }
00356 }
00357
00358 if (master_channelp && master_channelp->mLoopedThisFrame)
00359 {
00360
00361
00362 for (iter = mAllSources.begin(); iter != mAllSources.end(); ++iter)
00363 {
00364 LLAudioSource *sourcep = iter->second;
00365
00366 if (!sourcep->isSyncSlave())
00367 {
00368
00369 continue;
00370 }
00371
00372 LLAudioChannel *channelp = sourcep->getChannel();
00373 if (!channelp)
00374 {
00375
00376 continue;
00377 }
00378
00379 if (!channelp->isPlaying())
00380 {
00381
00382
00383 if (sync_masterp->getChannel())
00384 {
00385 channelp->playSynced(master_channelp);
00386 channelp->setWaiting(FALSE);
00387 }
00388 }
00389 }
00390 }
00391
00392
00393 commitDeferredChanges();
00394
00395
00396 for (i = 0; i < MAX_BUFFERS; i++)
00397 {
00398 if (mBuffers[i])
00399 {
00400 if (!mBuffers[i]->mInUse && mBuffers[i]->mLastUseTimer.getElapsedTimeF32() > 30.f)
00401 {
00402
00403 mBuffers[i]->mAudioDatap->mBufferp = NULL;
00404 delete mBuffers[i];
00405 mBuffers[i] = NULL;
00406 }
00407 }
00408 }
00409
00410
00411
00412 for (i = 0; i < MAX_CHANNELS; i++)
00413 {
00414 if (mChannels[i])
00415 {
00416 mChannels[i]->mLoopedThisFrame = FALSE;
00417 }
00418 }
00419
00420
00421 gAudioDecodeMgrp->processQueue(max_decode_time);
00422
00423
00424
00425
00426 startNextTransfer();
00427 }
00428
00429 BOOL LLAudioEngine::updateBufferForData(LLAudioData *adp, const LLUUID &audio_uuid)
00430 {
00431 if (!adp)
00432 {
00433 return FALSE;
00434 }
00435
00436
00437
00438
00439
00440
00441 if (!adp->getBuffer())
00442 {
00443 if (adp->hasDecodedData())
00444 {
00445 adp->load();
00446 }
00447 else if (adp->hasLocalData())
00448 {
00449 if (audio_uuid.notNull())
00450 {
00451 gAudioDecodeMgrp->addDecodeRequest(audio_uuid);
00452 }
00453 }
00454 else
00455 {
00456 return FALSE;
00457 }
00458 }
00459 return TRUE;
00460 }
00461
00462
00463 void LLAudioEngine::enableWind(BOOL enable)
00464 {
00465 if (enable && (!mEnableWind))
00466 {
00467 initWind();
00468 mEnableWind = enable;
00469 }
00470 else if (mEnableWind && (!enable))
00471 {
00472 mEnableWind = enable;
00473 cleanupWind();
00474 }
00475 }
00476
00477
00478 LLAudioBuffer *LLAudioEngine::getFreeBuffer()
00479 {
00480 S32 i;
00481 for (i = 0; i < MAX_BUFFERS; i++)
00482 {
00483 if (!mBuffers[i])
00484 {
00485 mBuffers[i] = createBuffer();
00486 return mBuffers[i];
00487 }
00488 }
00489
00490
00491
00492 F32 max_age = -1.f;
00493 S32 buffer_id = -1;
00494 for (i = 0; i < MAX_BUFFERS; i++)
00495 {
00496 if (mBuffers[i])
00497 {
00498 if (!mBuffers[i]->mInUse)
00499 {
00500 if (mBuffers[i]->mLastUseTimer.getElapsedTimeF32() > max_age)
00501 {
00502 max_age = mBuffers[i]->mLastUseTimer.getElapsedTimeF32();
00503 buffer_id = i;
00504 }
00505 }
00506 }
00507 }
00508
00509 if (buffer_id >= 0)
00510 {
00511 llinfos << "Taking over unused buffer " << buffer_id << llendl;
00512
00513 mBuffers[buffer_id]->mAudioDatap->mBufferp = NULL;
00514 delete mBuffers[buffer_id];
00515 mBuffers[buffer_id] = createBuffer();
00516 return mBuffers[buffer_id];
00517 }
00518 return NULL;
00519 }
00520
00521
00522 LLAudioChannel * LLAudioEngine::getFreeChannel(const F32 priority)
00523 {
00524 S32 i;
00525 for (i = 0; i < mNumChannels; i++)
00526 {
00527 if (!mChannels[i])
00528 {
00529
00530 mChannels[i] = createChannel();
00531 return mChannels[i];
00532 }
00533 else
00534 {
00535
00536 if (!mChannels[i]->isPlaying() && !mChannels[i]->isWaiting())
00537 {
00538 mChannels[i]->cleanup();
00539 if (mChannels[i]->getSource())
00540 {
00541 mChannels[i]->getSource()->setChannel(NULL);
00542 }
00543 return mChannels[i];
00544 }
00545 }
00546 }
00547
00548
00549
00550 F32 min_priority = 10000.f;
00551 LLAudioChannel *min_channelp = NULL;
00552
00553 for (i = 0; i < mNumChannels; i++)
00554 {
00555 LLAudioChannel *channelp = mChannels[i];
00556 LLAudioSource *sourcep = channelp->getSource();
00557 if (sourcep->getPriority() < min_priority)
00558 {
00559 min_channelp = channelp;
00560 min_priority = sourcep->getPriority();
00561 }
00562 }
00563
00564 if (min_priority > priority || !min_channelp)
00565 {
00566
00567 return NULL;
00568 }
00569
00570
00571 min_channelp->cleanup();
00572 min_channelp->getSource()->setChannel(NULL);
00573 return min_channelp;
00574 }
00575
00576
00577 void LLAudioEngine::cleanupBuffer(LLAudioBuffer *bufferp)
00578 {
00579 S32 i;
00580 for (i = 0; i < MAX_BUFFERS; i++)
00581 {
00582 if (mBuffers[i] == bufferp)
00583 {
00584 delete mBuffers[i];
00585 mBuffers[i] = NULL;
00586 }
00587 }
00588 }
00589
00590
00591 BOOL LLAudioEngine::preloadSound(const LLUUID &uuid)
00592 {
00593 gAudiop->getAudioData(uuid);
00594
00595
00596 if (gAudioDecodeMgrp->addDecodeRequest(uuid))
00597 {
00598
00599 return TRUE;
00600 }
00601
00602
00603
00604
00605 return FALSE;
00606 }
00607
00608
00609 BOOL LLAudioEngine::isWindEnabled()
00610 {
00611 return mEnableWind;
00612 }
00613
00614
00615 void LLAudioEngine::setMuted(BOOL muted)
00616 {
00617 mMuted = muted;
00618 enableWind(!mMuted);
00619 }
00620
00621
00622 void LLAudioEngine::setMasterGain(const F32 gain)
00623 {
00624 mMasterGain = gain;
00625 setInternalGain(gain);
00626 }
00627
00628 F32 LLAudioEngine::getMasterGain()
00629 {
00630 return mMasterGain;
00631 }
00632
00633 F32 LLAudioEngine::getInternetStreamGain()
00634 {
00635 return mInternetStreamGain;
00636 }
00637
00638 void LLAudioEngine::setMaxWindGain(F32 gain)
00639 {
00640 mMaxWindGain = gain;
00641 }
00642
00643
00644 F64 LLAudioEngine::mapWindVecToGain(LLVector3 wind_vec)
00645 {
00646 F64 gain = 0.0;
00647
00648 gain = wind_vec.magVec();
00649
00650 if (gain)
00651 {
00652 if (gain > 20)
00653 {
00654 gain = 20;
00655 }
00656 gain = gain/20.0;
00657 }
00658
00659 return (gain);
00660 }
00661
00662
00663 F64 LLAudioEngine::mapWindVecToPitch(LLVector3 wind_vec)
00664 {
00665 LLVector3 listen_right;
00666 F64 theta;
00667
00668
00669 LLVector3 norm_wind = wind_vec;
00670 norm_wind.normVec();
00671 listen_right.setVec(1.0,0.0,0.0);
00672
00673
00674 theta = acos(norm_wind * listen_right);
00675
00676
00677 theta /= F_PI;
00678
00679
00680 if (theta > 0.5) theta = 1.0-theta;
00681 if (theta < 0) theta = 0;
00682
00683 return (theta);
00684 }
00685
00686
00687 F64 LLAudioEngine::mapWindVecToPan(LLVector3 wind_vec)
00688 {
00689 LLVector3 listen_right;
00690 F64 theta;
00691
00692
00693 listen_right.setVec(1.0,0.0,0.0);
00694
00695 LLVector3 norm_wind = wind_vec;
00696 norm_wind.normVec();
00697
00698
00699 theta = acos(norm_wind * listen_right);
00700
00701
00702 theta /= F_PI;
00703
00704 return (theta);
00705 }
00706
00707
00708 void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_id, const F32 gain, const LLVector3d &pos_global)
00709 {
00710
00711
00712
00713 if (mMuted)
00714 {
00715 return;
00716 }
00717
00718 LLUUID source_id;
00719 source_id.generate();
00720
00721 LLAudioSource *asp = new LLAudioSource(source_id, owner_id, gain);
00722 gAudiop->addAudioSource(asp);
00723 if (pos_global.isExactlyZero())
00724 {
00725 asp->setAmbient(TRUE);
00726 }
00727 else
00728 {
00729 asp->setPositionGlobal(pos_global);
00730 }
00731 asp->updatePriority();
00732 asp->play(audio_uuid);
00733 }
00734
00735
00736 void LLAudioEngine::setListenerPos(LLVector3 aVec)
00737 {
00738 mListenerp->setPosition(aVec);
00739 }
00740
00741
00742 LLVector3 LLAudioEngine::getListenerPos()
00743 {
00744 if (mListenerp)
00745 {
00746 return(mListenerp->getPosition());
00747 }
00748 else
00749 {
00750 return(LLVector3::zero);
00751 }
00752 }
00753
00754
00755 void LLAudioEngine::setListenerVelocity(LLVector3 aVec)
00756 {
00757 mListenerp->setVelocity(aVec);
00758 }
00759
00760
00761 void LLAudioEngine::translateListener(LLVector3 aVec)
00762 {
00763 mListenerp->translate(aVec);
00764 }
00765
00766
00767 void LLAudioEngine::orientListener(LLVector3 up, LLVector3 at)
00768 {
00769 mListenerp->orient(up, at);
00770 }
00771
00772
00773 void LLAudioEngine::setListener(LLVector3 pos, LLVector3 vel, LLVector3 up, LLVector3 at)
00774 {
00775 mListenerp->set(pos,vel,up,at);
00776 }
00777
00778
00779 void LLAudioEngine::setDopplerFactor(F32 factor)
00780 {
00781 if (mListenerp)
00782 {
00783 mListenerp->setDopplerFactor(factor);
00784 }
00785 }
00786
00787
00788 F32 LLAudioEngine::getDopplerFactor()
00789 {
00790 if (mListenerp)
00791 {
00792 return mListenerp->getDopplerFactor();
00793 }
00794 else
00795 {
00796 return 0.f;
00797 }
00798 }
00799
00800
00801 void LLAudioEngine::setDistanceFactor(F32 factor)
00802 {
00803 if (mListenerp)
00804 {
00805 mListenerp->setDistanceFactor(factor);
00806 }
00807 }
00808
00809
00810 F32 LLAudioEngine::getDistanceFactor()
00811 {
00812 if (mListenerp)
00813 {
00814 return mListenerp->getDistanceFactor();
00815 }
00816 else
00817 {
00818 return 0.f;
00819 }
00820 }
00821
00822
00823 void LLAudioEngine::setRolloffFactor(F32 factor)
00824 {
00825 if (mListenerp)
00826 {
00827 mListenerp->setRolloffFactor(factor);
00828 }
00829 }
00830
00831
00832 F32 LLAudioEngine::getRolloffFactor()
00833 {
00834 if (mListenerp)
00835 {
00836 return mListenerp->getRolloffFactor();
00837 }
00838 else
00839 {
00840 return 0.f;
00841 }
00842 }
00843
00844
00845 void LLAudioEngine::commitDeferredChanges()
00846 {
00847 mListenerp->commitDeferredChanges();
00848 }
00849
00850
00851 LLAudioSource *LLAudioEngine::findAudioSource(const LLUUID &source_id)
00852 {
00853 source_map::iterator iter;
00854 iter = mAllSources.find(source_id);
00855
00856 if (iter == mAllSources.end())
00857 {
00858 return NULL;
00859 }
00860 else
00861 {
00862 return iter->second;
00863 }
00864 }
00865
00866
00867 LLAudioData *LLAudioEngine::getAudioData(const LLUUID &audio_uuid)
00868 {
00869 data_map::iterator iter;
00870 iter = mAllData.find(audio_uuid);
00871 if (iter == mAllData.end())
00872 {
00873
00874 LLAudioData *adp = new LLAudioData(audio_uuid);
00875 mAllData[audio_uuid] = adp;
00876 return adp;
00877 }
00878 else
00879 {
00880 return iter->second;
00881 }
00882 }
00883
00884 void LLAudioEngine::addAudioSource(LLAudioSource *asp)
00885 {
00886 mAllSources[asp->getID()] = asp;
00887 }
00888
00889
00890 void LLAudioEngine::cleanupAudioSource(LLAudioSource *asp)
00891 {
00892 source_map::iterator iter;
00893 iter = mAllSources.find(asp->getID());
00894 if (iter == mAllSources.end())
00895 {
00896 llwarns << "Cleaning up unknown audio source!" << llendl;
00897 return;
00898 }
00899 delete asp;
00900 mAllSources.erase(iter);
00901 }
00902
00903
00904 BOOL LLAudioEngine::hasDecodedFile(const LLUUID &uuid)
00905 {
00906 char uuid_str[UUID_STR_LENGTH];
00907 uuid.toString(uuid_str);
00908
00909 std::string wav_path;
00910 wav_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str);
00911 wav_path += ".dsf";
00912
00913 if (gDirUtilp->fileExists(wav_path))
00914 {
00915 return TRUE;
00916 }
00917 else
00918 {
00919 return FALSE;
00920 }
00921 }
00922
00923
00924 BOOL LLAudioEngine::hasLocalFile(const LLUUID &uuid)
00925 {
00926
00927 return gVFS->getExists(uuid, LLAssetType::AT_SOUND);
00928 }
00929
00930
00931 void LLAudioEngine::startNextTransfer()
00932 {
00933
00934 if (mCurrentTransfer.notNull() || getMuted())
00935 {
00936
00937 return;
00938 }
00939
00940
00941
00942 LLUUID asset_id;
00943 S32 i;
00944 LLAudioSource *asp = NULL;
00945 LLAudioData *adp = NULL;
00946 data_map::iterator data_iter;
00947
00948
00949 F32 max_pri = -1.f;
00950 for (i = 0; i < MAX_CHANNELS; i++)
00951 {
00952 if (!mChannels[i])
00953 {
00954 continue;
00955 }
00956
00957 asp = mChannels[i]->getSource();
00958 if (!asp)
00959 {
00960 continue;
00961 }
00962 if (asp->getPriority() <= max_pri)
00963 {
00964 continue;
00965 }
00966
00967 if (asp->getPriority() <= max_pri)
00968 {
00969 continue;
00970 }
00971
00972 adp = asp->getCurrentData();
00973 if (!adp)
00974 {
00975 continue;
00976 }
00977
00978 if (!adp->hasLocalData() && adp->hasValidData())
00979 {
00980 asset_id = adp->getID();
00981 max_pri = asp->getPriority();
00982 }
00983 }
00984
00985
00986 if (asset_id.isNull())
00987 {
00988 max_pri = -1.f;
00989 for (i = 0; i < MAX_CHANNELS; i++)
00990 {
00991 if (!mChannels[i])
00992 {
00993 continue;
00994 }
00995
00996 LLAudioSource *asp;
00997 asp = mChannels[i]->getSource();
00998 if (!asp)
00999 {
01000 continue;
01001 }
01002
01003 if (asp->getPriority() <= max_pri)
01004 {
01005 continue;
01006 }
01007
01008 adp = asp->getQueuedData();
01009 if (!adp)
01010 {
01011 continue;
01012 }
01013
01014 if (!adp->hasLocalData() && adp->hasValidData())
01015 {
01016 asset_id = adp->getID();
01017 max_pri = asp->getPriority();
01018 }
01019 }
01020 }
01021
01022
01023 if (asset_id.isNull())
01024 {
01025 max_pri = -1.f;
01026 for (i = 0; i < MAX_CHANNELS; i++)
01027 {
01028 if (!mChannels[i])
01029 {
01030 continue;
01031 }
01032
01033 LLAudioSource *asp;
01034 asp = mChannels[i]->getSource();
01035 if (!asp)
01036 {
01037 continue;
01038 }
01039
01040 if (asp->getPriority() <= max_pri)
01041 {
01042 continue;
01043 }
01044
01045
01046 for (data_iter = asp->mPreloadMap.begin(); data_iter != asp->mPreloadMap.end(); data_iter++)
01047 {
01048 LLAudioData *adp = data_iter->second;
01049 if (!adp)
01050 {
01051 continue;
01052 }
01053
01054 if (!adp->hasLocalData() && adp->hasValidData())
01055 {
01056 asset_id = adp->getID();
01057 max_pri = asp->getPriority();
01058 }
01059 }
01060 }
01061 }
01062
01063
01064 if (asset_id.isNull())
01065 {
01066 max_pri = -1.f;
01067 source_map::iterator source_iter;
01068 for (source_iter = mAllSources.begin(); source_iter != mAllSources.end(); source_iter++)
01069 {
01070 asp = source_iter->second;
01071 if (!asp)
01072 {
01073 continue;
01074 }
01075
01076 if (asp->getPriority() <= max_pri)
01077 {
01078 continue;
01079 }
01080
01081 adp = asp->getCurrentData();
01082 if (adp && !adp->hasLocalData() && adp->hasValidData())
01083 {
01084 asset_id = adp->getID();
01085 max_pri = asp->getPriority();
01086 continue;
01087 }
01088
01089 adp = asp->getQueuedData();
01090 if (adp && !adp->hasLocalData() && adp->hasValidData())
01091 {
01092 asset_id = adp->getID();
01093 max_pri = asp->getPriority();
01094 continue;
01095 }
01096
01097 for (data_iter = asp->mPreloadMap.begin(); data_iter != asp->mPreloadMap.end(); data_iter++)
01098 {
01099 LLAudioData *adp = data_iter->second;
01100 if (!adp)
01101 {
01102 continue;
01103 }
01104
01105 if (!adp->hasLocalData() && adp->hasValidData())
01106 {
01107 asset_id = adp->getID();
01108 max_pri = asp->getPriority();
01109 break;
01110 }
01111 }
01112 }
01113 }
01114
01115 if (asset_id.notNull())
01116 {
01117 llinfos << "Getting asset data for: " << asset_id << llendl;
01118 gAudiop->mCurrentTransfer = asset_id;
01119 gAudiop->mCurrentTransferTimer.reset();
01120 gAssetStorage->getAssetData(asset_id, LLAssetType::AT_SOUND,
01121 assetCallback, NULL);
01122 }
01123 else
01124 {
01125
01126 }
01127 }
01128
01129
01130
01131 void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 result_code, LLExtStat ext_status)
01132 {
01133 if (result_code)
01134 {
01135 llinfos << "Boom, error in audio file transfer: " << LLAssetStorage::getErrorString( result_code ) << " (" << result_code << ")" << llendl;
01136
01137 LLAudioData *adp = gAudiop->getAudioData(uuid);
01138 if (adp)
01139 {
01140 adp->setHasValidData(FALSE);
01141 adp->setHasLocalData(FALSE);
01142 adp->setHasDecodedData(FALSE);
01143 }
01144 }
01145 else
01146 {
01147 LLAudioData *adp = gAudiop->getAudioData(uuid);
01148 if (!adp)
01149 {
01150
01151 llwarns << "Got asset callback without audio data for " << uuid << llendl;
01152 }
01153 else
01154 {
01155 adp->setHasValidData(TRUE);
01156 adp->setHasLocalData(TRUE);
01157 gAudioDecodeMgrp->addDecodeRequest(uuid);
01158 }
01159 }
01160 gAudiop->mCurrentTransfer = LLUUID::null;
01161 gAudiop->startNextTransfer();
01162 }
01163
01164
01165
01166
01167
01168
01169
01170 LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32 gain)
01171 : mID(id),
01172 mOwnerID(owner_id),
01173 mPriority(0.f),
01174 mGain(gain),
01175 mAmbient(FALSE),
01176 mLoop(FALSE),
01177 mSyncMaster(FALSE),
01178 mSyncSlave(FALSE),
01179 mQueueSounds(FALSE),
01180 mPlayedOnce(FALSE),
01181 mChannelp(NULL),
01182 mCurrentDatap(NULL),
01183 mQueuedDatap(NULL)
01184 {
01185 }
01186
01187
01188 LLAudioSource::~LLAudioSource()
01189 {
01190 if (mChannelp)
01191 {
01192
01193 mChannelp->setSource(NULL);
01194 mChannelp = NULL;
01195 }
01196 }
01197
01198
01199 void LLAudioSource::setChannel(LLAudioChannel *channelp)
01200 {
01201 if (channelp == mChannelp)
01202 {
01203 return;
01204 }
01205
01206 mChannelp = channelp;
01207 }
01208
01209
01210 void LLAudioSource::update()
01211 {
01212 if (!getCurrentBuffer())
01213 {
01214 if (getCurrentData())
01215 {
01216
01217
01218 if (getCurrentData()->load())
01219 {
01220 play(getCurrentData()->getID());
01221 }
01222 }
01223 }
01224 }
01225
01226 void LLAudioSource::updatePriority()
01227 {
01228 if (isAmbient())
01229 {
01230 mPriority = 1.f;
01231 }
01232 else
01233 {
01234
01235 LLVector3 dist_vec;
01236 dist_vec.setVec(getPositionGlobal());
01237 dist_vec -= gAudiop->getListenerPos();
01238 F32 dist_squared = llmax(1.f, dist_vec.magVecSquared());
01239
01240 mPriority = mGain / dist_squared;
01241 }
01242 }
01243
01244 BOOL LLAudioSource::setupChannel()
01245 {
01246 LLAudioData *adp = getCurrentData();
01247
01248 if (!adp->getBuffer())
01249 {
01250
01251
01252 return FALSE;
01253 }
01254
01255
01256 if (!mChannelp)
01257 {
01258
01259 updatePriority();
01260
01261 setChannel(gAudiop->getFreeChannel(getPriority()));
01262 }
01263
01264 if (!mChannelp)
01265 {
01266
01267
01268
01269
01270 return FALSE;
01271 }
01272
01273 mChannelp->setSource(this);
01274 return TRUE;
01275 }
01276
01277
01278 BOOL LLAudioSource::play(const LLUUID &audio_uuid)
01279 {
01280 if (audio_uuid.isNull())
01281 {
01282 if (getChannel())
01283 {
01284 getChannel()->setSource(NULL);
01285 setChannel(NULL);
01286 addAudioData(NULL, TRUE);
01287 }
01288 }
01289
01290 mAgeTimer.reset();
01291
01292 LLAudioData *adp = gAudiop->getAudioData(audio_uuid);
01293
01294 BOOL has_buffer = gAudiop->updateBufferForData(adp, audio_uuid);
01295
01296
01297 addAudioData(adp);
01298
01299 if (!has_buffer)
01300 {
01301
01302 return FALSE;
01303 }
01304
01305 if (!setupChannel())
01306 {
01307 return FALSE;
01308 }
01309
01310 if (isSyncSlave())
01311 {
01312
01313
01314 getChannel()->setWaiting(TRUE);
01315 return TRUE;
01316 }
01317
01318 getChannel()->play();
01319 return TRUE;
01320 }
01321
01322
01323 BOOL LLAudioSource::isDone()
01324 {
01325 const F32 MAX_AGE = 60.f;
01326 const F32 MAX_UNPLAYED_AGE = 15.f;
01327 if (isLoop())
01328 {
01329
01330 return FALSE;
01331 }
01332
01333
01334 if (hasPendingPreloads())
01335 {
01336 return FALSE;
01337 }
01338
01339 if (mQueuedDatap)
01340 {
01341
01342 return FALSE;
01343 }
01344
01345 F32 elapsed = mAgeTimer.getElapsedTimeF32();
01346
01347
01348 if (!mChannelp)
01349 {
01350 if ((elapsed > MAX_UNPLAYED_AGE) || mPlayedOnce)
01351 {
01352
01353
01354
01355 return TRUE;
01356 }
01357 else
01358 {
01359 return FALSE;
01360 }
01361 }
01362
01363 if (mChannelp->isPlaying())
01364 {
01365 if (elapsed > MAX_AGE)
01366 {
01367
01368 return TRUE;
01369 }
01370 else
01371 {
01372
01373 return FALSE;
01374 }
01375 }
01376
01377 if ((elapsed > MAX_UNPLAYED_AGE) || mPlayedOnce)
01378 {
01379
01380 return TRUE;
01381 }
01382
01383 return FALSE;
01384 }
01385
01386
01387 void LLAudioSource::addAudioData(LLAudioData *adp, const BOOL set_current)
01388 {
01389
01390
01391 if (set_current)
01392 {
01393 if (!mCurrentDatap)
01394 {
01395 mCurrentDatap = adp;
01396 if (mChannelp)
01397 {
01398 mChannelp->updateBuffer();
01399 mChannelp->play();
01400 }
01401
01402
01403 gAudiop->startNextTransfer();
01404 return;
01405 }
01406 else if (mQueueSounds)
01407 {
01408
01409
01410 if (mQueuedDatap)
01411 {
01412
01413
01414 return;
01415 }
01416
01417 if (adp == mCurrentDatap && isLoop())
01418 {
01419
01420
01421 return;
01422 }
01423 mQueuedDatap = adp;
01424
01425
01426 gAudiop->startNextTransfer();
01427 }
01428 else
01429 {
01430 if (mCurrentDatap != adp)
01431 {
01432
01433
01434
01435 mCurrentDatap = adp;
01436 if (mChannelp)
01437 {
01438 mChannelp->updateBuffer();
01439 mChannelp->play();
01440 }
01441
01442 gAudiop->startNextTransfer();
01443 }
01444 }
01445 }
01446 else
01447 {
01448
01449 mPreloadMap[adp->getID()] = adp;
01450 gAudiop->startNextTransfer();
01451 }
01452 }
01453
01454
01455 BOOL LLAudioSource::hasPendingPreloads() const
01456 {
01457
01458 data_map::const_iterator iter;
01459 for (iter = mPreloadMap.begin(); iter != mPreloadMap.end(); iter++)
01460 {
01461 LLAudioData *adp = iter->second;
01462 if (!adp->hasDecodedData())
01463 {
01464
01465 return TRUE;
01466 }
01467 }
01468
01469 return FALSE;
01470 }
01471
01472
01473 LLAudioData *LLAudioSource::getCurrentData()
01474 {
01475 return mCurrentDatap;
01476 }
01477
01478 LLAudioData *LLAudioSource::getQueuedData()
01479 {
01480 return mQueuedDatap;
01481 }
01482
01483 LLAudioBuffer *LLAudioSource::getCurrentBuffer()
01484 {
01485 if (!mCurrentDatap)
01486 {
01487 return NULL;
01488 }
01489
01490 return mCurrentDatap->getBuffer();
01491 }
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501 LLAudioChannel::LLAudioChannel() :
01502 mCurrentSourcep(NULL),
01503 mCurrentBufferp(NULL),
01504 mLoopedThisFrame(FALSE),
01505 mWaiting(FALSE)
01506 {
01507 }
01508
01509
01510 LLAudioChannel::~LLAudioChannel()
01511 {
01512
01513
01514 if (mCurrentSourcep)
01515 {
01516 mCurrentSourcep->setChannel(NULL);
01517 }
01518 mCurrentBufferp = NULL;
01519 }
01520
01521
01522 void LLAudioChannel::setSource(LLAudioSource *sourcep)
01523 {
01524
01525
01526 if (!sourcep)
01527 {
01528
01529
01530 cleanup();
01531 mCurrentSourcep = NULL;
01532 mWaiting = FALSE;
01533 return;
01534 }
01535
01536 if (sourcep == mCurrentSourcep)
01537 {
01538
01539
01540 }
01541
01542 mCurrentSourcep = sourcep;
01543 updateBuffer();
01544 update3DPosition();
01545 }
01546
01547
01548 BOOL LLAudioChannel::updateBuffer()
01549 {
01550 if (!mCurrentSourcep)
01551 {
01552
01553
01554 return FALSE;
01555 }
01556
01557 LLAudioBuffer *bufferp = mCurrentSourcep->getCurrentBuffer();
01558 if (bufferp == mCurrentBufferp)
01559 {
01560 if (bufferp)
01561 {
01562
01563 bufferp->mLastUseTimer.reset();
01564 bufferp->mInUse = TRUE;
01565 }
01566 return FALSE;
01567 }
01568
01569
01570
01571
01572
01573 cleanup();
01574
01575 mCurrentBufferp = bufferp;
01576 if (bufferp)
01577 {
01578 bufferp->mLastUseTimer.reset();
01579 bufferp->mInUse = TRUE;
01580 }
01581
01582 if (!mCurrentBufferp)
01583 {
01584
01585 return FALSE;
01586 }
01587
01588 return TRUE;
01589 }
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599 LLAudioData::LLAudioData(const LLUUID &uuid) :
01600 mID(uuid),
01601 mBufferp(NULL),
01602 mHasLocalData(FALSE),
01603 mHasDecodedData(FALSE),
01604 mHasValidData(TRUE)
01605 {
01606 if (uuid.isNull())
01607 {
01608
01609 return;
01610 }
01611
01612 if (gAudiop->hasDecodedFile(uuid))
01613 {
01614
01615 mHasLocalData = TRUE;
01616 mHasDecodedData = TRUE;
01617 }
01618 else if (gAssetStorage->hasLocalAsset(uuid, LLAssetType::AT_SOUND))
01619 {
01620 mHasLocalData = TRUE;
01621 }
01622 }
01623
01624
01625 BOOL LLAudioData::load()
01626 {
01627
01628 if (mBufferp)
01629 {
01630
01631 llinfos << "Already have a buffer for this sound, don't bother loading!" << llendl;
01632 return TRUE;
01633 }
01634
01635 mBufferp = gAudiop->getFreeBuffer();
01636 if (!mBufferp)
01637 {
01638
01639 llinfos << "Not able to allocate a new audio buffer, aborting." << llendl;
01640 return FALSE;
01641 }
01642
01643 char uuid_str[UUID_STR_LENGTH];
01644 char wav_path[MAX_PATH];
01645 mID.toString(uuid_str);
01646 snprintf(wav_path, MAX_PATH, "%s.dsf",gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str).c_str());
01647
01648 if (!mBufferp->loadWAV(wav_path))
01649 {
01650
01651 gAudiop->cleanupBuffer(mBufferp);
01652 mBufferp = NULL;
01653
01654 return FALSE;
01655 }
01656 mBufferp->mAudioDatap = this;
01657 return TRUE;
01658 }
01659
01660