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
|