/indra/newview/llvoicevisualizer.cpp

https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 625 lines · 341 code · 122 blank · 162 comment · 25 complexity · 2f1a68c129be1a7decad2a2724bbb9f6 MD5 · raw file

  1. /**
  2. * @file llvoicevisualizer.cpp
  3. * @brief Draws in-world speaking indicators.
  4. *
  5. * $LicenseInfo:firstyear=2000&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. //----------------------------------------------------------------------
  27. // Voice Visualizer
  28. // author: JJ Ventrella
  29. // (information about this stuff can be found in "llvoicevisualizer.h")
  30. //----------------------------------------------------------------------
  31. #include "llviewerprecompiledheaders.h"
  32. #include "llviewercontrol.h"
  33. #include "llglheaders.h"
  34. #include "llsphere.h"
  35. #include "llvoicevisualizer.h"
  36. #include "llviewercamera.h"
  37. #include "llviewerobject.h"
  38. #include "llviewertexture.h"
  39. #include "llviewertexturelist.h"
  40. #include "llvoiceclient.h"
  41. #include "llrender.h"
  42. //brent's wave image
  43. //29de489d-0491-fb00-7dab-f9e686d31e83
  44. //--------------------------------------------------------------------------------------
  45. // sound symbol constants
  46. //--------------------------------------------------------------------------------------
  47. const F32 HEIGHT_ABOVE_HEAD = 0.3f; // how many meters vertically above the av's head the voice symbol will appear
  48. const F32 RED_THRESHOLD = LLVoiceClient::OVERDRIVEN_POWER_LEVEL; // value above which speaking amplitude causes the voice symbol to turn red
  49. const F32 GREEN_THRESHOLD = 0.2f; // value above which speaking amplitude causes the voice symbol to turn green
  50. const F32 FADE_OUT_DURATION = 0.4f; // how many seconds it takes for a pair of waves to fade away
  51. const F32 EXPANSION_RATE = 1.0f; // how many seconds it takes for the waves to expand to twice their original size
  52. const F32 EXPANSION_MAX = 1.5f; // maximum size scale to which the waves can expand before popping back to 1.0
  53. const F32 WAVE_WIDTH_SCALE = 0.03f; // base width of the waves
  54. const F32 WAVE_HEIGHT_SCALE = 0.02f; // base height of the waves
  55. const F32 BASE_BRIGHTNESS = 0.7f; // gray level of the voice indicator when quiet (below green threshold)
  56. const F32 DOT_SIZE = 0.05f; // size of the dot billboard texture
  57. const F32 DOT_OPACITY = 0.7f; // how opaque the dot is
  58. const F32 WAVE_MOTION_RATE = 1.5f; // scalar applied to consecutive waves as a function of speaking amplitude
  59. //--------------------------------------------------------------------------------------
  60. // gesticulation constants
  61. //--------------------------------------------------------------------------------------
  62. const F32 DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE = 0.2f;
  63. const F32 DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE = 1.0f;
  64. //--------------------------------------------------------------------------------------
  65. // other constants
  66. //--------------------------------------------------------------------------------------
  67. const F32 ONE_HALF = 1.0f; // to clarify intent and reduce magic numbers in the code.
  68. const LLVector3 WORLD_UPWARD_DIRECTION = LLVector3( 0.0f, 0.0f, 1.0f ); // Z is up in SL
  69. //------------------------------------------------------------------
  70. // handles parameter updates
  71. //------------------------------------------------------------------
  72. static bool handleVoiceVisualizerPrefsChanged(const LLSD& newvalue)
  73. {
  74. // Note: Ignore the specific event value, we look up the ones we want
  75. LLVoiceVisualizer::setPreferences();
  76. return true;
  77. }
  78. //------------------------------------------------------------------
  79. // Initialize the statics
  80. //------------------------------------------------------------------
  81. bool LLVoiceVisualizer::sPrefsInitialized = false;
  82. BOOL LLVoiceVisualizer::sLipSyncEnabled = FALSE;
  83. F32* LLVoiceVisualizer::sOoh = NULL;
  84. F32* LLVoiceVisualizer::sAah = NULL;
  85. U32 LLVoiceVisualizer::sOohs = 0;
  86. U32 LLVoiceVisualizer::sAahs = 0;
  87. F32 LLVoiceVisualizer::sOohAahRate = 0.0f;
  88. F32* LLVoiceVisualizer::sOohPowerTransfer = NULL;
  89. U32 LLVoiceVisualizer::sOohPowerTransfers = 0;
  90. F32 LLVoiceVisualizer::sOohPowerTransfersf = 0.0f;
  91. F32* LLVoiceVisualizer::sAahPowerTransfer = NULL;
  92. U32 LLVoiceVisualizer::sAahPowerTransfers = 0;
  93. F32 LLVoiceVisualizer::sAahPowerTransfersf = 0.0f;
  94. //-----------------------------------------------
  95. // constructor
  96. //-----------------------------------------------
  97. LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )
  98. :LLHUDEffect( type )
  99. {
  100. mCurrentTime = mTimer.getTotalSeconds();
  101. mPreviousTime = mCurrentTime;
  102. mStartTime = mCurrentTime;
  103. mVoiceSourceWorldPosition = LLVector3( 0.0f, 0.0f, 0.0f );
  104. mSpeakingAmplitude = 0.0f;
  105. mCurrentlySpeaking = false;
  106. mVoiceEnabled = false;
  107. mMinGesticulationAmplitude = DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE;
  108. mMaxGesticulationAmplitude = DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE;
  109. mSoundSymbol.mActive = true;
  110. mSoundSymbol.mPosition = LLVector3( 0.0f, 0.0f, 0.0f );
  111. mTimer.reset();
  112. const char* sound_level_img[] =
  113. {
  114. "voice_meter_dot.j2c",
  115. "voice_meter_rings.j2c",
  116. "voice_meter_rings.j2c",
  117. "voice_meter_rings.j2c",
  118. "voice_meter_rings.j2c",
  119. "voice_meter_rings.j2c",
  120. "voice_meter_rings.j2c"
  121. };
  122. for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
  123. {
  124. mSoundSymbol.mWaveFadeOutStartTime [i] = mCurrentTime;
  125. mSoundSymbol.mTexture [i] = LLViewerTextureManager::getFetchedTextureFromFile(sound_level_img[i], FALSE, LLViewerTexture::BOOST_UI);
  126. mSoundSymbol.mWaveActive [i] = false;
  127. mSoundSymbol.mWaveOpacity [i] = 1.0f;
  128. mSoundSymbol.mWaveExpansion [i] = 1.0f;
  129. }
  130. mSoundSymbol.mTexture[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
  131. // The first instance loads the initial state from prefs.
  132. if (!sPrefsInitialized)
  133. {
  134. setPreferences();
  135. // Set up our listener to get updates on all prefs values we care about.
  136. gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
  137. gSavedSettings.getControl("LipSyncOohAahRate")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
  138. gSavedSettings.getControl("LipSyncOoh")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
  139. gSavedSettings.getControl("LipSyncAah")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
  140. gSavedSettings.getControl("LipSyncOohPowerTransfer")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
  141. gSavedSettings.getControl("LipSyncAahPowerTransfer")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
  142. sPrefsInitialized = true;
  143. }
  144. }//---------------------------------------------------
  145. //---------------------------------------------------
  146. void LLVoiceVisualizer::setMinGesticulationAmplitude( F32 m )
  147. {
  148. mMinGesticulationAmplitude = m;
  149. }//---------------------------------------------------
  150. //---------------------------------------------------
  151. void LLVoiceVisualizer::setMaxGesticulationAmplitude( F32 m )
  152. {
  153. mMaxGesticulationAmplitude = m;
  154. }//---------------------------------------------------
  155. //---------------------------------------------------
  156. void LLVoiceVisualizer::setVoiceEnabled( bool v )
  157. {
  158. mVoiceEnabled = v;
  159. }//---------------------------------------------------
  160. //---------------------------------------------------
  161. void LLVoiceVisualizer::setStartSpeaking()
  162. {
  163. mStartTime = mTimer.getTotalSeconds();
  164. mCurrentlySpeaking = true;
  165. mSoundSymbol.mActive = true;
  166. }//---------------------------------------------------
  167. //---------------------------------------------------
  168. bool LLVoiceVisualizer::getCurrentlySpeaking()
  169. {
  170. return mCurrentlySpeaking;
  171. }//---------------------------------------------------
  172. //---------------------------------------------------
  173. void LLVoiceVisualizer::setStopSpeaking()
  174. {
  175. mCurrentlySpeaking = false;
  176. mSpeakingAmplitude = 0.0f;
  177. }//---------------------------------------------------
  178. //---------------------------------------------------
  179. void LLVoiceVisualizer::setSpeakingAmplitude( F32 a )
  180. {
  181. mSpeakingAmplitude = a;
  182. }//---------------------------------------------------
  183. //---------------------------------------------------
  184. void LLVoiceVisualizer::setPreferences( )
  185. {
  186. sLipSyncEnabled = gSavedSettings.getBOOL("LipSyncEnabled");
  187. sOohAahRate = gSavedSettings.getF32("LipSyncOohAahRate");
  188. std::string oohString = gSavedSettings.getString("LipSyncOoh");
  189. lipStringToF32s (oohString, sOoh, sOohs);
  190. std::string aahString = gSavedSettings.getString("LipSyncAah");
  191. lipStringToF32s (aahString, sAah, sAahs);
  192. std::string oohPowerString = gSavedSettings.getString("LipSyncOohPowerTransfer");
  193. lipStringToF32s (oohPowerString, sOohPowerTransfer, sOohPowerTransfers);
  194. sOohPowerTransfersf = (F32) sOohPowerTransfers;
  195. std::string aahPowerString = gSavedSettings.getString("LipSyncAahPowerTransfer");
  196. lipStringToF32s (aahPowerString, sAahPowerTransfer, sAahPowerTransfers);
  197. sAahPowerTransfersf = (F32) sAahPowerTransfers;
  198. }//---------------------------------------------------
  199. //---------------------------------------------------
  200. // convert a string of digits to an array of floats.
  201. // the result for each digit is the value of the
  202. // digit multiplied by 0.11
  203. //---------------------------------------------------
  204. void LLVoiceVisualizer::lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s )
  205. {
  206. delete[] out_F32s; // get rid of the current array
  207. count_F32s = in_string.length();
  208. if (count_F32s == 0)
  209. {
  210. // we don't like zero length arrays
  211. count_F32s = 1;
  212. out_F32s = new F32[1];
  213. out_F32s[0] = 0.0f;
  214. }
  215. else
  216. {
  217. out_F32s = new F32[count_F32s];
  218. for (U32 i=0; i<count_F32s; i++)
  219. {
  220. // we convert the characters 0 to 9 to their numeric value
  221. // anything else we take the low order four bits with a ceiling of 9
  222. U8 digit = in_string[i];
  223. U8 four_bits = digit % 16;
  224. if (four_bits > 9)
  225. {
  226. four_bits = 9;
  227. }
  228. out_F32s[i] = 0.11f * (F32) four_bits;
  229. }
  230. }
  231. }//---------------------------------------------------
  232. //--------------------------------------------------------------------------
  233. // find the amount to blend the ooh and aah mouth morphs
  234. //--------------------------------------------------------------------------
  235. void LLVoiceVisualizer::lipSyncOohAah( F32& ooh, F32& aah )
  236. {
  237. if( ( sLipSyncEnabled == TRUE ) && mCurrentlySpeaking )
  238. {
  239. U32 transfer_index = (U32) (sOohPowerTransfersf * mSpeakingAmplitude);
  240. if (transfer_index >= sOohPowerTransfers)
  241. {
  242. transfer_index = sOohPowerTransfers - 1;
  243. }
  244. F32 transfer_ooh = sOohPowerTransfer[transfer_index];
  245. transfer_index = (U32) (sAahPowerTransfersf * mSpeakingAmplitude);
  246. if (transfer_index >= sAahPowerTransfers)
  247. {
  248. transfer_index = sAahPowerTransfers - 1;
  249. }
  250. F32 transfer_aah = sAahPowerTransfer[transfer_index];
  251. F64 current_time = mTimer.getTotalSeconds();
  252. F64 elapsed_time = current_time - mStartTime;
  253. U32 elapsed_frames = (U32) (elapsed_time * sOohAahRate);
  254. U32 elapsed_oohs = elapsed_frames % sOohs;
  255. U32 elapsed_aahs = elapsed_frames % sAahs;
  256. ooh = transfer_ooh * sOoh[elapsed_oohs];
  257. aah = transfer_aah * sAah[elapsed_aahs];
  258. /*
  259. llinfos << " elapsed frames " << elapsed_frames
  260. << " ooh " << ooh
  261. << " aah " << aah
  262. << " transfer ooh" << transfer_ooh
  263. << " transfer aah" << transfer_aah
  264. << " start time " << mStartTime
  265. << " current time " << current_time
  266. << " elapsed time " << elapsed_time
  267. << " elapsed oohs " << elapsed_oohs
  268. << " elapsed aahs " << elapsed_aahs
  269. << llendl;
  270. */
  271. }
  272. else
  273. {
  274. ooh = 0.0f;
  275. aah = 0.0f;
  276. }
  277. }//---------------------------------------------------
  278. //---------------------------------------------------
  279. // this method is inherited from HUD Effect
  280. //---------------------------------------------------
  281. void LLVoiceVisualizer::render()
  282. {
  283. if ( ! mVoiceEnabled )
  284. {
  285. return;
  286. }
  287. if ( mSoundSymbol.mActive )
  288. {
  289. mPreviousTime = mCurrentTime;
  290. mCurrentTime = mTimer.getTotalSeconds();
  291. //---------------------------------------------------------------
  292. // set the sound symbol position over the source (avatar's head)
  293. //---------------------------------------------------------------
  294. mSoundSymbol.mPosition = mVoiceSourceWorldPosition + WORLD_UPWARD_DIRECTION * HEIGHT_ABOVE_HEAD;
  295. //---------------------------------------------------------------
  296. // some gl state
  297. //---------------------------------------------------------------
  298. LLGLSPipelineAlpha alpha_blend;
  299. LLGLDepthTest depth(GL_TRUE, GL_FALSE);
  300. //-------------------------------------------------------------
  301. // create coordinates of the geometry for the dot
  302. //-------------------------------------------------------------
  303. LLViewerCamera* camera = LLViewerCamera::getInstance();
  304. LLVector3 l = camera->getLeftAxis() * DOT_SIZE;
  305. LLVector3 u = camera->getUpAxis() * DOT_SIZE;
  306. LLVector3 bottomLeft = mSoundSymbol.mPosition + l - u;
  307. LLVector3 bottomRight = mSoundSymbol.mPosition - l - u;
  308. LLVector3 topLeft = mSoundSymbol.mPosition + l + u;
  309. LLVector3 topRight = mSoundSymbol.mPosition - l + u;
  310. //-----------------------------
  311. // bind texture 0 (the dot)
  312. //-----------------------------
  313. gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[0]);
  314. //-------------------------------------------------------------
  315. // now render the dot
  316. //-------------------------------------------------------------
  317. gGL.color4fv( LLColor4( 1.0f, 1.0f, 1.0f, DOT_OPACITY ).mV );
  318. gGL.begin( LLRender::TRIANGLE_STRIP );
  319. gGL.texCoord2i( 0, 0 ); gGL.vertex3fv( bottomLeft.mV );
  320. gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
  321. gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
  322. gGL.end();
  323. gGL.begin( LLRender::TRIANGLE_STRIP );
  324. gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
  325. gGL.texCoord2i( 1, 1 ); gGL.vertex3fv( topRight.mV );
  326. gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
  327. gGL.end();
  328. //--------------------------------------------------------------------------------------
  329. // if currently speaking, trigger waves (1 through 6) based on speaking amplitude
  330. //--------------------------------------------------------------------------------------
  331. if ( mCurrentlySpeaking )
  332. {
  333. F32 min = 0.2f;
  334. F32 max = 0.7f;
  335. F32 fraction = ( mSpeakingAmplitude - min ) / ( max - min );
  336. // in case mSpeakingAmplitude > max....
  337. if ( fraction > 1.0f )
  338. {
  339. fraction = 1.0f;
  340. }
  341. S32 level = 1 + (int)( fraction * ( NUM_VOICE_SYMBOL_WAVES - 2 ) );
  342. for (int i=0; i<level+1; i++)
  343. {
  344. mSoundSymbol.mWaveActive [i] = true;
  345. mSoundSymbol.mWaveOpacity [i] = 1.0f;
  346. mSoundSymbol.mWaveFadeOutStartTime [i] = mCurrentTime;
  347. }
  348. } // if currently speaking
  349. //---------------------------------------------------
  350. // determine color
  351. //---------------------------------------------------
  352. F32 red = 0.0f;
  353. F32 green = 0.0f;
  354. F32 blue = 0.0f;
  355. if ( mSpeakingAmplitude < RED_THRESHOLD )
  356. {
  357. if ( mSpeakingAmplitude < GREEN_THRESHOLD )
  358. {
  359. red = BASE_BRIGHTNESS;
  360. green = BASE_BRIGHTNESS;
  361. blue = BASE_BRIGHTNESS;
  362. }
  363. else
  364. {
  365. //---------------------------------------------------
  366. // fade from gray to bright green
  367. //---------------------------------------------------
  368. F32 fraction = ( mSpeakingAmplitude - GREEN_THRESHOLD ) / ( 1.0f - GREEN_THRESHOLD );
  369. red = BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS );
  370. green = BASE_BRIGHTNESS + fraction * ( 1.0f - BASE_BRIGHTNESS );
  371. blue = BASE_BRIGHTNESS - ( fraction * BASE_BRIGHTNESS );
  372. }
  373. }
  374. else
  375. {
  376. //---------------------------------------------------
  377. // redish
  378. //---------------------------------------------------
  379. red = 1.0f;
  380. green = 0.2f;
  381. blue = 0.2f;
  382. }
  383. for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
  384. {
  385. if ( mSoundSymbol.mWaveActive[i] )
  386. {
  387. F32 fadeOutFraction = (F32)( mCurrentTime - mSoundSymbol.mWaveFadeOutStartTime[i] ) / FADE_OUT_DURATION;
  388. mSoundSymbol.mWaveOpacity[i] = 1.0f - fadeOutFraction;
  389. if ( mSoundSymbol.mWaveOpacity[i] < 0.0f )
  390. {
  391. mSoundSymbol.mWaveFadeOutStartTime [i] = mCurrentTime;
  392. mSoundSymbol.mWaveOpacity [i] = 0.0f;
  393. mSoundSymbol.mWaveActive [i] = false;
  394. }
  395. //----------------------------------------------------------------------------------
  396. // This is where we calculate the expansion of the waves - that is, the
  397. // rate at which they are scaled greater than 1.0 so that they grow over time.
  398. //----------------------------------------------------------------------------------
  399. F32 timeSlice = (F32)( mCurrentTime - mPreviousTime );
  400. F32 waveSpeed = mSpeakingAmplitude * WAVE_MOTION_RATE;
  401. mSoundSymbol.mWaveExpansion[i] *= ( 1.0f + EXPANSION_RATE * timeSlice * waveSpeed );
  402. if ( mSoundSymbol.mWaveExpansion[i] > EXPANSION_MAX )
  403. {
  404. mSoundSymbol.mWaveExpansion[i] = 1.0f;
  405. }
  406. //----------------------------------------------------------------------------------
  407. // create geometry for the wave billboard textures
  408. //----------------------------------------------------------------------------------
  409. F32 width = i * WAVE_WIDTH_SCALE * mSoundSymbol.mWaveExpansion[i];
  410. F32 height = i * WAVE_HEIGHT_SCALE * mSoundSymbol.mWaveExpansion[i];
  411. LLVector3 l = camera->getLeftAxis() * width;
  412. LLVector3 u = camera->getUpAxis() * height;
  413. LLVector3 bottomLeft = mSoundSymbol.mPosition + l - u;
  414. LLVector3 bottomRight = mSoundSymbol.mPosition - l - u;
  415. LLVector3 topLeft = mSoundSymbol.mPosition + l + u;
  416. LLVector3 topRight = mSoundSymbol.mPosition - l + u;
  417. gGL.color4fv( LLColor4( red, green, blue, mSoundSymbol.mWaveOpacity[i] ).mV );
  418. gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[i]);
  419. //---------------------------------------------------
  420. // now, render the mofo
  421. //---------------------------------------------------
  422. gGL.begin( LLRender::TRIANGLE_STRIP );
  423. gGL.texCoord2i( 0, 0 ); gGL.vertex3fv( bottomLeft.mV );
  424. gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
  425. gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
  426. gGL.end();
  427. gGL.begin( LLRender::TRIANGLE_STRIP );
  428. gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV );
  429. gGL.texCoord2i( 1, 1 ); gGL.vertex3fv( topRight.mV );
  430. gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV );
  431. gGL.end();
  432. } //if ( mSoundSymbol.mWaveActive[i] )
  433. }// for loop
  434. }//if ( mSoundSymbol.mActive )
  435. }//---------------------------------------------------
  436. //---------------------------------------------------
  437. void LLVoiceVisualizer::setVoiceSourceWorldPosition( const LLVector3 &p )
  438. {
  439. mVoiceSourceWorldPosition = p;
  440. }//---------------------------------------------------
  441. //---------------------------------------------------
  442. VoiceGesticulationLevel LLVoiceVisualizer::getCurrentGesticulationLevel()
  443. {
  444. VoiceGesticulationLevel gesticulationLevel = VOICE_GESTICULATION_LEVEL_OFF; //default
  445. //-----------------------------------------------------------------------------------------
  446. // Within the range of gesticulation amplitudes, the sound signal is split into
  447. // three equal amplitude regimes, each specifying one of three gesticulation levels.
  448. //-----------------------------------------------------------------------------------------
  449. F32 range = mMaxGesticulationAmplitude - mMinGesticulationAmplitude;
  450. if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.5f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_HIGH; }
  451. else if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.25f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_MEDIUM; }
  452. else if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.00000f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_LOW; }
  453. return gesticulationLevel;
  454. }//---------------------------------------------------
  455. //------------------------------------
  456. // Destructor
  457. //------------------------------------
  458. LLVoiceVisualizer::~LLVoiceVisualizer()
  459. {
  460. }//----------------------------------------------
  461. //---------------------------------------------------
  462. // "packData" is inherited from HUDEffect
  463. //---------------------------------------------------
  464. void LLVoiceVisualizer::packData(LLMessageSystem *mesgsys)
  465. {
  466. // Pack the default data
  467. LLHUDEffect::packData(mesgsys);
  468. // TODO -- pack the relevant data for voice effects
  469. // we'll come up with some cool configurations....TBD
  470. //U8 packed_data[41];
  471. //mesgsys->addBinaryDataFast(_PREHASH_TypeData, packed_data, 41);
  472. U8 packed_data = 0;
  473. mesgsys->addBinaryDataFast(_PREHASH_TypeData, &packed_data, 1);
  474. }
  475. //---------------------------------------------------
  476. // "unpackData" is inherited from HUDEffect
  477. //---------------------------------------------------
  478. void LLVoiceVisualizer::unpackData(LLMessageSystem *mesgsys, S32 blocknum)
  479. {
  480. // TODO -- find the speaker, unpack binary data, set the properties of this effect
  481. /*
  482. LLHUDEffect::unpackData(mesgsys, blocknum);
  483. LLUUID source_id;
  484. LLUUID target_id;
  485. S32 size = mesgsys->getSizeFast(_PREHASH_Effect, blocknum, _PREHASH_TypeData);
  486. if (size != 1)
  487. {
  488. llwarns << "Voice effect with bad size " << size << llendl;
  489. return;
  490. }
  491. mesgsys->getBinaryDataFast(_PREHASH_Effect, _PREHASH_TypeData, packed_data, 1, blocknum);
  492. */
  493. }
  494. //------------------------------------------------------------------
  495. // this method is inherited from HUD Effect
  496. //------------------------------------------------------------------
  497. void LLVoiceVisualizer::markDead()
  498. {
  499. mCurrentlySpeaking = false;
  500. mVoiceEnabled = false;
  501. mSoundSymbol.mActive = false;
  502. LLHUDEffect::markDead();
  503. }//------------------------------------------------------------------