summaryrefslogtreecommitdiff
path: root/indra/newview/llvoicevisualizer.h
blob: 5da592c48edbd271c917963871ebd0dc5a76cd01 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/** 
 * @file llvoicevisualizer.h
 * @brief Draws in-world speaking indicators.
 *
 * $LicenseInfo:firstyear=2000&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * 
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

//--------------------------------------------------------------------
//
// VOICE VISUALIZER
// author: JJ Ventrella, Linden Lab
// (latest update to this info: Jan 18, 2007)
//
// The Voice Visualizer is responsible for taking realtime signals from actual users speaking and 
// visualizing this speech in two forms: 
//
// (1) as a dynamic sound symbol (also referred to as the "voice indicator" that appears over the avatar's head
// (2) as gesticulation events that are used to trigger avatr gestures 
//
// The input for the voice visualizer is a continual stream of voice amplitudes. 

//-----------------------------------------------------------------------------
#ifndef LL_VOICE_VISUALIZER_H
#define LL_VOICE_VISUALIZER_H

#define XXX_STINSON_CHUI_REWORK // temporarily re-enabling the in-world voice-dot
#ifdef XXX_STINSON_CHUI_REWORK
#include "llhudeffect.h"
#else // XXX_STINSON_CHUI_REWORK
#include "llpointer.h"
#endif // XXX_STINSON_CHUI_REWORK

//-----------------------------------------------------------------------------------------------
// The values of voice gesticulation represent energy levels for avatar animation, based on 
// amplitude surge events parsed from the voice signal. These are made available so that 
// the appropriate kind of avatar animation can be triggered, and thereby simulate the physical
// motion effects of speech. It is recommended that multiple body parts be animated as well as 
// lips, such as head, shoulders, and hands, with large gestures used when the energy level is high.
//-----------------------------------------------------------------------------------------------
enum VoiceGesticulationLevel
{
	VOICE_GESTICULATION_LEVEL_OFF = -1,
	VOICE_GESTICULATION_LEVEL_LOW = 0,
	VOICE_GESTICULATION_LEVEL_MEDIUM,
	VOICE_GESTICULATION_LEVEL_HIGH,
	NUM_VOICE_GESTICULATION_LEVELS
};

#ifdef XXX_STINSON_CHUI_REWORK
const static int NUM_VOICE_SYMBOL_WAVES = 7;
#endif // XXX_STINSON_CHUI_REWORK

//----------------------------------------------------
// LLVoiceVisualizer class 
//----------------------------------------------------
#ifdef XXX_STINSON_CHUI_REWORK
class LLVoiceVisualizer : public LLHUDEffect
#else // XXX_STINSON_CHUI_REWORK
class LLVoiceVisualizer : public LLRefCount
#endif // XXX_STINSON_CHUI_REWORK
{
	//---------------------------------------------------
	// public methods 
	//---------------------------------------------------
	public:
#ifdef XXX_STINSON_CHUI_REWORK
		LLVoiceVisualizer( const U8 type );	//constructor
#else // XXX_STINSON_CHUI_REWORK
		LLVoiceVisualizer();	//constructor
#endif // XXX_STINSON_CHUI_REWORK
		~LLVoiceVisualizer();					//destructor

#ifdef XXX_STINSON_CHUI_REWORK
		void					setVoiceSourceWorldPosition( const LLVector3 &p );		// this should be the position of the speaking avatar's head
		void					setMinGesticulationAmplitude( F32 );					// the lower range of meaningful amplitude for setting gesticulation level 
		void					setMaxGesticulationAmplitude( F32 );					// the upper range of meaningful amplitude for setting gesticulation level 
#endif // XXX_STINSON_CHUI_REWORK
		void					setStartSpeaking();										// tell me when the av starts speaking
#ifdef XXX_STINSON_CHUI_REWORK
		void					setVoiceEnabled( bool );								// tell me whether or not the user is voice enabled
#endif // XXX_STINSON_CHUI_REWORK
		void					setSpeakingAmplitude( F32 );							// tell me how loud the av is speaking (ranges from 0 to 1)
		void					setStopSpeaking();										// tell me when the av stops speaking
		bool					getCurrentlySpeaking();									// the get for the above set
		VoiceGesticulationLevel	getCurrentGesticulationLevel();							// based on voice amplitude, I'll give you the current "energy level" of avatar speech
		void					lipSyncOohAah( F32& ooh, F32& aah );
#ifdef XXX_STINSON_CHUI_REWORK
		void					render();												// inherited from HUD Effect
		void 					packData(LLMessageSystem *mesgsys);						// inherited from HUD Effect
		void 					unpackData(LLMessageSystem *mesgsys, S32 blocknum);		// inherited from HUD Effect
		void					markDead();											// inherited from HUD Effect
		
		//----------------------------------------------------------------------------------------------
		// "setMaxGesticulationAmplitude" and "setMinGesticulationAmplitude" allow for the tuning of the 
		// gesticulation level detector to be responsive to different kinds of signals. For instance, we 
		// may find that the average voice amplitude rarely exceeds 0.7 (in a range from 0 to 1), and 
		// therefore we may want to set 0.7 as the max, so we can more easily catch all the variance 
		// within that range. Also, we may find that there is often noise below a certain range like 0.1, 
		// and so we would want to set 0.1 as the min so as not to accidentally use this as signal.
		//----------------------------------------------------------------------------------------------
		void setMaxGesticulationAmplitude(); 
		void setMinGesticulationAmplitude(); 
#endif // XXX_STINSON_CHUI_REWORK

	//---------------------------------------------------
	// private members 
	//---------------------------------------------------
	private:
		static bool				handleVoiceVisualizerPrefsChanged(const LLSD& newvalue);
		static void				setPreferences( );
		static void				lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s ); // convert a string of digits to an array of floats

#ifdef XXX_STINSON_CHUI_REWORK
		struct SoundSymbol
		{
			F32						mWaveExpansion			[ NUM_VOICE_SYMBOL_WAVES ];
			bool					mWaveActive				[ NUM_VOICE_SYMBOL_WAVES ];
			F64						mWaveFadeOutStartTime	[ NUM_VOICE_SYMBOL_WAVES ];
			F32						mWaveOpacity			[ NUM_VOICE_SYMBOL_WAVES ];
			LLPointer<LLViewerFetchedTexture>	mTexture				[ NUM_VOICE_SYMBOL_WAVES ];
			bool					mActive;
			LLVector3				mPosition;
		};
#endif // XXX_STINSON_CHUI_REWORK

		LLFrameTimer			mTimer;							// so I can ask the current time in seconds
		F64						mStartTime;						// time in seconds when speaking started
#ifdef XXX_STINSON_CHUI_REWORK
		F64						mCurrentTime;					// current time in seconds, captured every step
		F64						mPreviousTime;					// copy of "current time" from last frame
		SoundSymbol				mSoundSymbol;					// the sound symbol that appears over the avatar's head
		bool					mVoiceEnabled;					// if off, no rendering should happen
#endif // XXX_STINSON_CHUI_REWORK
		bool					mCurrentlySpeaking;				// is the user currently speaking?
#ifdef XXX_STINSON_CHUI_REWORK
		LLVector3				mVoiceSourceWorldPosition;		// give this to me every step - I need it to update the sound symbol
#endif // XXX_STINSON_CHUI_REWORK
		F32						mSpeakingAmplitude;				// this should be set as often as possible when the user is speaking
		F32						mMaxGesticulationAmplitude;		// this is the upper-limit of the envelope of detectable gesticulation leves
		F32						mMinGesticulationAmplitude;		// this is the lower-limit of the envelope of detectable gesticulation leves
		
	//---------------------------------------------------
	// private static members 
	//---------------------------------------------------

		static BOOL	  sLipSyncEnabled;		 // 0 disabled, 1 babble loop
		static bool	  sPrefsInitialized;	 // the first instance will initialize the static members
		static F32*	  sOoh;					 // the babble loop of amplitudes for the ooh morph
		static F32*	  sAah;					 // the babble loop of amplitudes for the ooh morph
		static U32	  sOohs;				 // the number of entries in the ooh loop
		static U32	  sAahs;				 // the number of entries in the aah loop
		static F32	  sOohAahRate;			 // frames per second for the babble loop
		static F32*	  sOohPowerTransfer;	 // the power transfer characteristics for the ooh amplitude
		static U32	  sOohPowerTransfers;	 // the number of entries in the ooh transfer characteristics
		static F32	  sOohPowerTransfersf;	 // the number of entries in the ooh transfer characteristics as a float
		static F32*	  sAahPowerTransfer;	 // the power transfer characteristics for the aah amplitude
		static U32	  sAahPowerTransfers;	 // the number of entries in the aah transfer characteristics
		static F32	  sAahPowerTransfersf;	 // the number of entries in the aah transfer characteristics as a float

};//-----------------------------------------------------------------
 //   end of LLVoiceVisualizer class
//------------------------------------------------------------------

#endif //LL_VOICE_VISUALIZER_H