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