PageRenderTime 165ms CodeModel.GetById 3ms app.highlight 144ms RepoModel.GetById 9ms app.codeStats 0ms

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