llaudiosourcevo.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /**
  2. * @file llaudiosourcevo.cpp
  3. * @author Douglas Soo, James Cook
  4. * @brief Audio sources attached to viewer objects
  5. *
  6. * $LicenseInfo:firstyear=2006&license=viewergpl$
  7. *
  8. * Copyright (c) 2006-2009, Linden Research, Inc.
  9. *
  10. * Second Life Viewer Source Code
  11. * The source code in this file ("Source Code") is provided by Linden Lab
  12. * to you under the terms of the GNU General Public License, version 2.0
  13. * ("GPL"), unless you have obtained a separate licensing agreement
  14. * ("Other License"), formally executed by you and Linden Lab. Terms of
  15. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  16. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  17. *
  18. * There are special exceptions to the terms and conditions of the GPL as
  19. * it is applied to this Source Code. View the full text of the exception
  20. * in the file doc/FLOSS-exception.txt in this software distribution, or
  21. * online at
  22. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  23. *
  24. * By copying, modifying or distributing this software, you acknowledge
  25. * that you have read and understood your obligations described above,
  26. * and agree to abide by those obligations.
  27. *
  28. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  29. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  30. * COMPLETENESS OR PERFORMANCE.
  31. * $/LicenseInfo$
  32. */
  33. #include "llviewerprecompiledheaders.h"
  34. #include "llaudiosourcevo.h"
  35. #include "llagent.h"
  36. #include "llappviewer.h" // For gFrameTimeSeconds
  37. #include "llmutelist.h"
  38. #include "llviewercontrol.h" // For gSavedSettings
  39. #include "llviewerparcelmgr.h"
  40. // Update mutes at most every half of a second
  41. constexpr F32 UPDATE_INTERVAL = 0.5f;
  42. LLAudioSourceVO::LLAudioSourceVO(const LLUUID& sound_id,
  43. const LLUUID& owner_id, F32 gain,
  44. LLViewerObject* objectp)
  45. : LLAudioSource(sound_id, owner_id, gain, LLAudioEngine::AUDIO_TYPE_SFX),
  46. mObjectp(objectp),
  47. mLastUpdate(0.f)
  48. {
  49. update();
  50. }
  51. LLAudioSourceVO::~LLAudioSourceVO()
  52. {
  53. if (mObjectp)
  54. {
  55. mObjectp->clearAttachedSound();
  56. }
  57. mObjectp = NULL;
  58. }
  59. void LLAudioSourceVO::setGain(F32 gain)
  60. {
  61. mGain = llclamp(gain, 0.f, 1.f);
  62. }
  63. bool LLAudioSourceVO::isInCutOffRadius(const LLVector3d& pos_global,
  64. F32 cutoff) const
  65. {
  66. static LLCachedControl<S32> ear_mode(gSavedSettings, "VoiceEarLocation");
  67. LLVector3d to_vec;
  68. if (ear_mode == 1 || ear_mode == 2)
  69. {
  70. to_vec = pos_global - gAgent.getPositionGlobal();
  71. }
  72. else
  73. {
  74. to_vec = pos_global - gAgent.getCameraPositionGlobal();
  75. }
  76. return (F32)to_vec.lengthSquared() < cutoff * cutoff;
  77. }
  78. void LLAudioSourceVO::checkCutOffRadius()
  79. {
  80. if (mSourceMuted || !mObjectp) return;
  81. F32 cutoff = mObjectp->getSoundCutOffRadius();
  82. if (cutoff < 0.1f)
  83. {
  84. // Consider cutoff below 0.1m as off (to avoid near zero comparison)
  85. return;
  86. }
  87. LLViewerObject* objectp = mObjectp;
  88. if (objectp->isAttachment())
  89. {
  90. while (objectp && !objectp->isAvatar())
  91. {
  92. objectp = (LLViewerObject*)objectp->getParent();
  93. }
  94. }
  95. if (objectp && !isInCutOffRadius(objectp->getPositionGlobal(), cutoff))
  96. {
  97. mSourceMuted = true;
  98. }
  99. }
  100. void LLAudioSourceVO::updateMute()
  101. {
  102. if (!mObjectp) return; // Paranoia
  103. bool is_attachment = mObjectp->isAttachment();
  104. LLViewerObject* parent = mObjectp;
  105. if (is_attachment)
  106. {
  107. while (parent && !parent->isAvatar())
  108. {
  109. parent = (LLViewerObject*)parent->getParent();
  110. }
  111. }
  112. bool mute = mCurrentDatap && mCurrentDatap->isBlocked();
  113. static LLCachedControl<bool> play_attached(gSavedSettings,
  114. "EnableAttachmentSounds");
  115. if (!mute && is_attachment && !play_attached && parent &&
  116. parent->getID() != gAgentID)
  117. {
  118. mute = true;
  119. }
  120. if (!mute)
  121. {
  122. LLVector3d pos_global;
  123. if (parent)
  124. {
  125. pos_global = parent->getPositionGlobal();
  126. }
  127. else
  128. {
  129. pos_global = mObjectp->getPositionGlobal();
  130. }
  131. if (!gViewerParcelMgr.canHearSound(pos_global))
  132. {
  133. mute = true;
  134. }
  135. else
  136. {
  137. F32 cutoff = mObjectp->getSoundCutOffRadius();
  138. if (cutoff > 0.1f && !isInCutOffRadius(pos_global, cutoff))
  139. {
  140. mute = true;
  141. }
  142. }
  143. }
  144. if (!mute)
  145. {
  146. if (LLMuteList::isMuted(mObjectp->getID()))
  147. {
  148. mute = true;
  149. }
  150. else if (LLMuteList::isMuted(mOwnerID, LLMute::flagObjectSounds))
  151. {
  152. mute = true;
  153. }
  154. else if (is_attachment && parent &&
  155. LLMuteList::isMuted(parent->getID()))
  156. {
  157. mute = true;
  158. }
  159. }
  160. if (mute != mSourceMuted)
  161. {
  162. mSourceMuted = mute;
  163. if (mSourceMuted)
  164. {
  165. // Stop the sound.
  166. play(LLUUID::null);
  167. }
  168. else
  169. {
  170. // Muted sounds keep their data at all times, because it is the
  171. // place where the audio UUID is stored. However, it is possible
  172. // that mCurrentDatap is NULL when this source did only preload
  173. // sounds.
  174. if (mCurrentDatap)
  175. {
  176. // Restart the sound.
  177. play(mCurrentDatap->getID());
  178. }
  179. }
  180. }
  181. }
  182. void LLAudioSourceVO::update()
  183. {
  184. if (!mObjectp || mObjectp->isDead())
  185. {
  186. mObjectp = NULL;
  187. mSourceMuted = true;
  188. return;
  189. }
  190. if (mLastUpdate + UPDATE_INTERVAL < gFrameTimeSeconds)
  191. {
  192. updateMute();
  193. mLastUpdate = gFrameTimeSeconds;
  194. }
  195. if (mSourceMuted)
  196. {
  197. return;
  198. }
  199. if (mObjectp->isHUDAttachment())
  200. {
  201. mPositionGlobal = gAgent.getCameraPositionGlobal();
  202. }
  203. else
  204. {
  205. mPositionGlobal = mObjectp->getPositionGlobal();
  206. }
  207. if (mObjectp->getSubParent())
  208. {
  209. mVelocity = mObjectp->getSubParent()->getVelocity();
  210. }
  211. else
  212. {
  213. mVelocity = mObjectp->getVelocity();
  214. }
  215. LLAudioSource::update();
  216. }