aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llvoiceclient.h
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/llvoiceclient.h')
-rw-r--r--linden/indra/newview/llvoiceclient.h523
1 files changed, 523 insertions, 0 deletions
diff --git a/linden/indra/newview/llvoiceclient.h b/linden/indra/newview/llvoiceclient.h
new file mode 100644
index 0000000..f65aa58
--- /dev/null
+++ b/linden/indra/newview/llvoiceclient.h
@@ -0,0 +1,523 @@
1/**
2 * @file llvoiceclient.h
3 * @brief Declaration of LLVoiceClient class which is the interface to the voice client process.
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * Second Life Viewer Source Code
8 * The source code in this file ("Source Code") is provided by Linden Lab
9 * to you under the terms of the GNU General Public License, version 2.0
10 * ("GPL"), unless you have obtained a separate licensing agreement
11 * ("Other License"), formally executed by you and Linden Lab. Terms of
12 * the GPL can be found in doc/GPL-license.txt in this distribution, or
13 * online at http://secondlife.com/developers/opensource/gplv2
14 *
15 * There are special exceptions to the terms and conditions of the GPL as
16 * it is applied to this Source Code. View the full text of the exception
17 * in the file doc/FLOSS-exception.txt in this software distribution, or
18 * online at http://secondlife.com/developers/opensource/flossexception
19 *
20 * By copying, modifying or distributing this software, you acknowledge
21 * that you have read and understood your obligations described above,
22 * and agree to abide by those obligations.
23 *
24 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
25 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
26 * COMPLETENESS OR PERFORMANCE.
27 */
28#ifndef LL_VOICE_CLIENT_H
29#define LL_VOICE_CLIENT_H
30
31// This would create a circular reference -- just do a forward definition of necessary class names.
32//#include "llvoavatar.h"
33class LLVOAvatar;
34class LLVivoxProtocolParser;
35
36#include "lliopipe.h"
37#include "llpumpio.h"
38#include "llchainio.h"
39#include "lliosocket.h"
40#include "v3math.h"
41#include "llframetimer.h"
42#include "llviewerregion.h"
43
44class LLVoiceClientParticipantObserver
45{
46public:
47 virtual ~LLVoiceClientParticipantObserver() { }
48 virtual void onChange() = 0;
49};
50
51class LLVoiceClientStatusObserver
52{
53public:
54 typedef enum e_voice_status_type
55 {
56 STATUS_LOGIN_RETRY,
57 STATUS_LOGGED_IN,
58 STATUS_JOINING,
59 STATUS_JOINED,
60 STATUS_LEFT_CHANNEL,
61 BEGIN_ERROR_STATUS,
62 ERROR_CHANNEL_FULL,
63 ERROR_CHANNEL_LOCKED,
64 ERROR_NOT_AVAILABLE,
65 ERROR_UNKNOWN
66 } EStatusType;
67
68 virtual ~LLVoiceClientStatusObserver() { }
69 virtual void onChange(EStatusType status, const std::string &channelURI, bool proximal) = 0;
70
71 static const char *status2string(EStatusType inStatus);
72};
73
74class LLVoiceClient: public LLSingleton<LLVoiceClient>
75{
76 LOG_CLASS(LLVoiceClient);
77 public:
78 LLVoiceClient();
79 ~LLVoiceClient();
80
81 public:
82 static void init(LLPumpIO *pump); // Call this once at application startup (creates connector)
83 static void terminate(); // Call this to clean up during shutdown
84
85 protected:
86 bool writeString(const std::string &str);
87
88 public:
89
90 enum serviceType
91 {
92 serviceTypeUnknown, // Unknown, returned if no data on the avatar is available
93 serviceTypeA, // spatialized local chat
94 serviceTypeB, // remote multi-party chat
95 serviceTypeC // one-to-one and small group chat
96 };
97 static F32 OVERDRIVEN_POWER_LEVEL;
98
99 /////////////////////////////
100 // session control messages
101 void connect();
102
103 void connectorCreate();
104 void connectorShutdown();
105
106 void requestVoiceAccountProvision(S32 retries = 3);
107 void userAuthorized(
108 const std::string& firstName,
109 const std::string& lastName,
110 const LLUUID &agentID);
111 void login(const std::string& accountName, const std::string &password);
112 void loginSendMessage();
113 void logout();
114 void logoutSendMessage();
115
116 void channelGetListSendMessage();
117 void sessionCreateSendMessage();
118 void sessionConnectSendMessage();
119 void sessionTerminate();
120 void sessionTerminateSendMessage();
121 void sessionTerminateByHandle(std::string &sessionHandle);
122
123 void getCaptureDevicesSendMessage();
124 void getRenderDevicesSendMessage();
125
126 void clearCaptureDevices();
127 void addCaptureDevice(const std::string& name);
128 void setCaptureDevice(const std::string& name);
129
130 void clearRenderDevices();
131 void addRenderDevice(const std::string& name);
132 void setRenderDevice(const std::string& name);
133
134 void tuningStart();
135 void tuningStop();
136 bool inTuningMode();
137
138 void tuningRenderStartSendMessage(const std::string& name, bool loop);
139 void tuningRenderStopSendMessage();
140
141 void tuningCaptureStartSendMessage(int duration);
142 void tuningCaptureStopSendMessage();
143
144 void tuningSetMicVolume(float volume);
145 void tuningSetSpeakerVolume(float volume);
146 float tuningGetEnergy(void);
147
148 // This returns true when it's safe to bring up the "device settings" dialog in the prefs.
149 // i.e. when the daemon is running and connected, and the device lists are populated.
150 bool deviceSettingsAvailable();
151
152 // Requery the vivox daemon for the current list of input/output devices.
153 // If you pass true for clearCurrentList, deviceSettingsAvailable() will be false until the query has completed
154 // (use this if you want to know when it's done).
155 // If you pass false, you'll have no way to know when the query finishes, but the device lists will not appear empty in the interim.
156 void refreshDeviceLists(bool clearCurrentList = true);
157
158 // Call this if the connection to the daemon terminates unexpectedly. It will attempt to reset everything and relaunch.
159 void daemonDied();
160
161 // Call this if we're just giving up on voice (can't provision an account, etc.). It will clean up and go away.
162 void giveUp();
163
164 /////////////////////////////
165 // Response/Event handlers
166 void connectorCreateResponse(int statusCode, std::string &statusString, std::string &connectorHandle);
167 void loginResponse(int statusCode, std::string &statusString, std::string &accountHandle);
168 void channelGetListResponse(int statusCode, std::string &statusString);
169 void sessionCreateResponse(int statusCode, std::string &statusString, std::string &sessionHandle);
170 void sessionConnectResponse(int statusCode, std::string &statusString);
171 void sessionTerminateResponse(int statusCode, std::string &statusString);
172 void logoutResponse(int statusCode, std::string &statusString);
173 void connectorShutdownResponse(int statusCode, std::string &statusString);
174
175 void loginStateChangeEvent(std::string &accountHandle, int statusCode, std::string &statusString, int state);
176 void sessionNewEvent(std::string &accountHandle, std::string &eventSessionHandle, int state, std::string &nameString, std::string &uriString);
177 void sessionStateChangeEvent(std::string &uriString, int statusCode, std::string &statusString, std::string &sessionHandle, int state, bool isChannel, std::string &nameString);
178 void participantStateChangeEvent(std::string &uriString, int statusCode, std::string &statusString, int state, std::string &nameString, std::string &displayNameString, int participantType);
179 void participantPropertiesEvent(std::string &uriString, int statusCode, std::string &statusString, bool isLocallyMuted, bool isModeratorMuted, bool isSpeaking, int volume, F32 energy);
180 void auxAudioPropertiesEvent(F32 energy);
181
182 void muteListChanged();
183
184 /////////////////////////////
185 // Sending updates of current state
186 void setCameraPosition(const LLVector3d &position, const LLVector3 &velocity, const LLMatrix3 &rot);
187 void setAvatarPosition(const LLVector3d &position, const LLVector3 &velocity, const LLMatrix3 &rot);
188 bool channelFromRegion(LLViewerRegion *region, std::string &name);
189 void leaveChannel(void); // call this on logout or teleport begin
190
191
192 void setMuteMic(bool muted); // Use this to mute the local mic (for when the client is minimized, etc), ignoring user PTT state.
193 void setUserPTTState(bool ptt);
194 bool getUserPTTState();
195 void toggleUserPTTState(void);
196 void setVoiceEnabled(bool enabled);
197 static bool voiceEnabled();
198 void setUsePTT(bool usePTT);
199 void setPTTIsToggle(bool PTTIsToggle);
200 void setPTTKey(std::string &key);
201 void setEarLocation(S32 loc);
202 void setVoiceVolume(F32 volume);
203 void setMicGain(F32 volume);
204 void setUserVolume(const LLUUID& id, F32 volume); // set's volume for specified agent, from 0-1 (where .5 is nominal)
205 void setVivoxDebugServerName(std::string &serverName);
206
207 // PTT key triggering
208 void keyDown(KEY key, MASK mask);
209 void keyUp(KEY key, MASK mask);
210 void middleMouseState(bool down);
211
212 /////////////////////////////
213 // Accessors for data related to nearby speakers
214 BOOL getVoiceEnabled(const LLUUID& id); // true if we've received data for this avatar
215 BOOL getIsSpeaking(const LLUUID& id);
216 F32 getCurrentPower(const LLUUID& id); // "power" is related to "amplitude" in a defined way. I'm just not sure what the formula is...
217 BOOL getPTTPressed(const LLUUID& id); // This is the inverse of the "locally muted" property.
218 BOOL getOnMuteList(const LLUUID& id);
219 F32 getUserVolume(const LLUUID& id);
220 LLString getDisplayName(const LLUUID& id);
221
222 // MBW -- XXX -- Not sure how to get this data out of the TVC
223 BOOL getUsingPTT(const LLUUID& id);
224 serviceType getServiceType(const LLUUID& id); // type of chat the user is involved in (see bHear scope doc for definitions of A/B/C)
225 std::string getGroupID(const LLUUID& id); // group ID if the user is in group chat (empty string if not applicable)
226
227 /////////////////////////////
228 BOOL getAreaVoiceDisabled(); // returns true if the area the avatar is in is speech-disabled.
229 // Use this to determine whether to show a "no speech" icon in the menu bar.
230
231 struct participantState
232 {
233 public:
234 participantState(const std::string &uri);
235 std::string mURI;
236 std::string mName;
237 std::string mDisplayName;
238 bool mPTT;
239 bool mIsSpeaking;
240 LLFrameTimer mSpeakingTimeout;
241 F32 mLastSpokeTimestamp;
242 F32 mPower;
243 int mVolume;
244 serviceType mServiceType;
245 std::string mGroupID;
246 bool mOnMuteList; // true if this avatar is on the user's mute list (and should be muted)
247 int mUserVolume;
248 bool mVolumeDirty; // true if this participant needs a volume command sent (either mOnMuteList or mUserVolume has changed)
249 bool mAvatarIDValid;
250 LLUUID mAvatarID;
251 };
252 typedef std::map<std::string, participantState*> participantMap;
253
254 participantState *findParticipant(const std::string &uri);
255 participantState *findParticipantByAvatar(LLVOAvatar *avatar);
256 participantState *findParticipantByID(const LLUUID& id);
257
258 participantMap *getParticipantList(void);
259
260 void addObserver(LLVoiceClientParticipantObserver* observer);
261 void removeObserver(LLVoiceClientParticipantObserver* observer);
262
263 void addStatusObserver(LLVoiceClientStatusObserver* observer);
264 void removeStatusObserver(LLVoiceClientStatusObserver* observer);
265
266 static void onAvatarNameLookup(const LLUUID& id, const char* first, const char* last, BOOL is_group, void* user_data);
267 typedef std::vector<std::string> deviceList;
268
269 deviceList *getCaptureDevices();
270 deviceList *getRenderDevices();
271
272 void setNonSpatialChannel(
273 const std::string &uri,
274 const std::string &credentials);
275 void setSpatialChannel(
276 const std::string &uri,
277 const std::string &credentials);
278 void callUser(LLUUID &uuid);
279 void answerInvite(std::string &sessionHandle, LLUUID& other_user_id);
280 void declineInvite(std::string &sessionHandle);
281 void leaveNonSpatialChannel();
282
283 // Returns the URI of the current channel, or an empty string if not currently in a channel.
284 // NOTE that it will return an empty string if it's in the process of joining a channel.
285 std::string getCurrentChannel();
286
287 // returns true iff the user is currently in a proximal (local spatial) channel.
288 // Note that gestures should only fire if this returns true.
289 bool inProximalChannel();
290
291 std::string sipURIFromID(const LLUUID &id);
292
293 private:
294
295 // internal state for a simple state machine. This is used to deal with the asynchronous nature of some of the messages.
296 // Note: if you change this list, please make corresponding changes to LLVoiceClient::state2string().
297 enum state
298 {
299 stateDisabled, // Voice is turned off.
300 stateStart, // Class is initialized, socket is created
301 stateDaemonLaunched, // Daemon has been launched
302 stateConnecting, // connect() call has been issued
303 stateIdle, // socket is connected, ready for messaging
304 stateConnectorStart, // connector needs to be started
305 stateConnectorStarting, // waiting for connector handle
306 stateConnectorStarted, // connector handle received
307 stateMicTuningNoLogin, // mic tuning before login
308 stateLoginRetry, // need to retry login (failed due to changing password)
309 stateLoginRetryWait, // waiting for retry timer
310 stateNeedsLogin, // send login request
311 stateLoggingIn, // waiting for account handle
312 stateLoggedIn, // account handle received
313 stateNoChannel, //
314 stateMicTuningLoggedIn, // mic tuning for a logged in user
315 stateSessionCreate, // need to send Session.Create command
316 stateSessionConnect, // need to send Session.Connect command
317 stateJoiningSession, // waiting for session handle
318 stateSessionJoined, // session handle received
319 stateRunning, // in session, steady state
320 stateLeavingSession, // waiting for terminate session response
321 stateSessionTerminated, // waiting for terminate session response
322
323 stateLoggingOut, // waiting for logout response
324 stateLoggedOut, // logout response received
325 stateConnectorStopping, // waiting for connector stop
326 stateConnectorStopped, // connector stop received
327
328 // We go to this state if the login fails because the account needs to be provisioned.
329
330 // error states. No way to recover from these yet.
331 stateConnectorFailed,
332 stateConnectorFailedWaiting,
333 stateLoginFailed,
334 stateLoginFailedWaiting,
335 stateJoinSessionFailed,
336 stateJoinSessionFailedWaiting,
337
338 stateJail // Go here when all else has failed. Nothing will be retried, we're done.
339 };
340
341 state mState;
342 bool mSessionTerminateRequested;
343 bool mNonSpatialChannel;
344
345 void setState(state inState);
346 state getState(void) { return mState; };
347 static const char *state2string(state inState);
348
349 void stateMachine();
350 static void idle(void *user_data);
351
352 LLHost mDaemonHost;
353 LLSocket::ptr_t mSocket;
354 bool mConnected;
355
356 void closeSocket(void);
357
358 LLPumpIO *mPump;
359 friend class LLVivoxProtocolParser;
360
361 std::string mAccountName;
362 std::string mAccountPassword;
363 std::string mAccountDisplayName;
364 std::string mAccountFirstName;
365 std::string mAccountLastName;
366
367 std::string mNextP2PSessionURI; // URI of the P2P session to join next
368 std::string mNextSessionURI; // URI of the session to join next
369 std::string mNextSessionHandle; // Session handle of the session to join next
370 std::string mNextSessionHash; // Password hash for the session to join next
371 bool mNextSessionSpatial; // Will next session be a spatial chat?
372 bool mNextSessionNoReconnect; // Next session should not auto-reconnect (i.e. user -> user chat)
373 bool mNextSessionResetOnClose; // If this is true, go back to spatial chat when the next session terminates.
374
375 std::string mSessionStateEventHandle; // session handle received in SessionStateChangeEvents
376 std::string mSessionStateEventURI; // session URI received in SessionStateChangeEvents
377
378 bool mTuningMode;
379 float mTuningEnergy;
380 std::string mTuningAudioFile;
381 int mTuningMicVolume;
382 bool mTuningMicVolumeDirty;
383 int mTuningSpeakerVolume;
384 bool mTuningSpeakerVolumeDirty;
385 bool mTuningCaptureRunning;
386
387 std::string mSpatialSessionURI;
388
389 bool mSessionResetOnClose;
390
391 int mVivoxErrorStatusCode;
392 std::string mVivoxErrorStatusString;
393
394 std::string mChannelName; // Name of the channel to be looked up
395 bool mAreaVoiceDisabled;
396 std::string mSessionURI; // URI of the session we're in.
397 bool mSessionP2P; // true if this session is a p2p call
398
399 S32 mCurrentParcelLocalID; // Used to detect parcel boundary crossings
400 std::string mCurrentRegionName; // Used to detect parcel boundary crossings
401
402 std::string mConnectorHandle; // returned by "Create Connector" message
403 std::string mAccountHandle; // returned by login message
404 std::string mSessionHandle; // returned by ?
405 U32 mCommandCookie;
406
407 std::string mAccountServerName;
408 std::string mAccountServerURI;
409
410 int mLoginRetryCount;
411
412 participantMap mParticipantMap;
413 bool mParticipantMapChanged;
414
415 deviceList mCaptureDevices;
416 deviceList mRenderDevices;
417
418 std::string mCaptureDevice;
419 std::string mRenderDevice;
420 bool mCaptureDeviceDirty;
421 bool mRenderDeviceDirty;
422
423 participantState *addParticipant(const std::string &uri);
424 // Note: after removeParticipant returns, the participant* that was passed to it will have been deleted.
425 // Take care not to use the pointer again after that.
426 void removeParticipant(participantState *participant);
427 void removeAllParticipants();
428
429 void updateMuteState(participantState *participant);
430
431 typedef std::map<std::string, std::string> channelMap;
432 channelMap mChannelMap;
433
434 // These are used by the parser when processing a channel list response.
435 void clearChannelMap(void);
436 void addChannelMapEntry(std::string &name, std::string &uri);
437 std::string findChannelURI(std::string &name);
438
439 // This should be called when the code detects we have changed parcels.
440 // It initiates the call to the server that gets the parcel channel.
441 void parcelChanged();
442
443 void switchChannel(std::string uri = "", bool spatial = true, bool noReconnect = false, std::string hash = "");
444 void joinSession(std::string handle, std::string uri);
445
446 std::string nameFromAvatar(LLVOAvatar *avatar);
447 std::string nameFromID(const LLUUID &id);
448 bool IDFromName(const std::string name, LLUUID &uuid);
449 std::string displayNameFromAvatar(LLVOAvatar *avatar);
450 std::string sipURIFromAvatar(LLVOAvatar *avatar);
451 std::string sipURIFromName(std::string &name);
452
453 void sendPositionalUpdate(void);
454
455 void buildSetCaptureDevice(std::ostringstream &stream);
456 void buildSetRenderDevice(std::ostringstream &stream);
457
458 void enforceTether(void);
459
460 bool mSpatialCoordsDirty;
461
462 LLVector3d mCameraPosition;
463 LLVector3d mCameraRequestedPosition;
464 LLVector3 mCameraVelocity;
465 LLMatrix3 mCameraRot;
466
467 LLVector3d mAvatarPosition;
468 LLVector3 mAvatarVelocity;
469 LLMatrix3 mAvatarRot;
470
471 bool mPTTDirty;
472 bool mPTT;
473
474 bool mUsePTT;
475 bool mPTTIsMiddleMouse;
476 KEY mPTTKey;
477 bool mPTTIsToggle;
478 bool mUserPTTState;
479 bool mMuteMic;
480
481 // Set to true when the mute state of someone in the participant list changes.
482 // The code will have to walk the list to find the changed participant(s).
483 bool mVolumeDirty;
484
485 enum
486 {
487 earLocCamera = 0, // ear at camera
488 earLocAvatar, // ear at avatar
489 earLocMixed // ear at avatar location/camera direction
490 };
491
492 S32 mEarLocation;
493
494 bool mSpeakerVolumeDirty;
495 bool mSpeakerMuteDirty;
496 int mSpeakerVolume;
497
498 int mMicVolume;
499 bool mMicVolumeDirty;
500
501 bool mVoiceEnabled;
502 bool mWriteInProgress;
503 std::string mWriteString;
504 size_t mWriteOffset;
505
506 LLTimer mUpdateTimer;
507
508 typedef std::set<LLVoiceClientParticipantObserver*> observer_set_t;
509 observer_set_t mObservers;
510
511 void notifyObservers();
512
513 typedef std::set<LLVoiceClientStatusObserver*> status_observer_set_t;
514 status_observer_set_t mStatusObservers;
515
516 void notifyStatusObservers(LLVoiceClientStatusObserver::EStatusType status);
517};
518
519extern LLVoiceClient *gVoiceClient;
520
521#endif //LL_VOICE_CLIENT_H
522
523