llvoiceclient.h

Go to the documentation of this file.
00001 
00031 #ifndef LL_VOICE_CLIENT_H
00032 #define LL_VOICE_CLIENT_H
00033 
00034 // This would create a circular reference -- just do a forward definition of necessary class names.
00035 //#include "llvoavatar.h"
00036 class LLVOAvatar;
00037 class LLVivoxProtocolParser;
00038 
00039 #include "lliopipe.h"
00040 #include "llpumpio.h"
00041 #include "llchainio.h"
00042 #include "lliosocket.h"
00043 #include "v3math.h"
00044 #include "llframetimer.h"
00045 #include "llviewerregion.h"
00046 
00047 class LLVoiceClientParticipantObserver
00048 {
00049 public:
00050         virtual ~LLVoiceClientParticipantObserver() { }
00051         virtual void onChange() = 0;
00052 };
00053 
00054 class LLVoiceClientStatusObserver
00055 {
00056 public:
00057         typedef enum e_voice_status_type
00058         {
00059                 // NOTE: when updating this enum, please also update the switch in
00060                 //  LLVoiceClientStatusObserver::status2string().
00061                 STATUS_LOGIN_RETRY,
00062                 STATUS_LOGGED_IN,
00063                 STATUS_JOINING,
00064                 STATUS_JOINED,
00065                 STATUS_LEFT_CHANNEL,
00066                 STATUS_VOICE_DISABLED,
00067                 BEGIN_ERROR_STATUS,
00068                 ERROR_CHANNEL_FULL,
00069                 ERROR_CHANNEL_LOCKED,
00070                 ERROR_NOT_AVAILABLE,
00071                 ERROR_UNKNOWN
00072         } EStatusType;
00073 
00074         virtual ~LLVoiceClientStatusObserver() { }
00075         virtual void onChange(EStatusType status, const std::string &channelURI, bool proximal) = 0;
00076 
00077         static const char *status2string(EStatusType inStatus);
00078 };
00079 
00080 class LLVoiceClient: public LLSingleton<LLVoiceClient>
00081 {
00082         LOG_CLASS(LLVoiceClient);
00083         public:
00084                 LLVoiceClient();        
00085                 ~LLVoiceClient();
00086                 
00087         public:
00088                 static void init(LLPumpIO *pump);       // Call this once at application startup (creates connector)
00089                 static void terminate();        // Call this to clean up during shutdown
00090                                                 
00091         protected:
00092                 bool writeString(const std::string &str);
00093 
00094         public:
00095                 
00096                 enum serviceType
00097                 {
00098                         serviceTypeUnknown,     // Unknown, returned if no data on the avatar is available
00099                         serviceTypeA,           // spatialized local chat
00100                         serviceTypeB,           // remote multi-party chat
00101                         serviceTypeC            // one-to-one and small group chat
00102                 };
00103                 static F32 OVERDRIVEN_POWER_LEVEL;
00104                                 
00106                 // session control messages
00107                 void connect();
00108 
00109                 void connectorCreate();
00110                 void connectorShutdown();
00111 
00112                 void requestVoiceAccountProvision(S32 retries = 3);
00113                 void userAuthorized(
00114                         const std::string& firstName,
00115                         const std::string& lastName,
00116                         const LLUUID &agentID);
00117                 void login(const std::string& accountName, const std::string &password);
00118                 void loginSendMessage();
00119                 void logout();
00120                 void logoutSendMessage();
00121                 
00122                 void channelGetListSendMessage();
00123                 void sessionCreateSendMessage();
00124                 void sessionConnectSendMessage();
00125                 void sessionTerminate();
00126                 void sessionTerminateSendMessage();
00127                 void sessionTerminateByHandle(std::string &sessionHandle);
00128                 
00129                 void getCaptureDevicesSendMessage();
00130                 void getRenderDevicesSendMessage();
00131                 
00132                 void clearCaptureDevices();
00133                 void addCaptureDevice(const std::string& name);
00134                 void setCaptureDevice(const std::string& name);
00135                 
00136                 void clearRenderDevices();
00137                 void addRenderDevice(const std::string& name);
00138                 void setRenderDevice(const std::string& name);
00139 
00140                 void tuningStart();
00141                 void tuningStop();
00142                 bool inTuningMode();
00143                 bool inTuningStates();
00144                 
00145                 void tuningRenderStartSendMessage(const std::string& name, bool loop);
00146                 void tuningRenderStopSendMessage();
00147 
00148                 void tuningCaptureStartSendMessage(int duration);
00149                 void tuningCaptureStopSendMessage();
00150                 
00151                 void tuningSetMicVolume(float volume);
00152                 void tuningSetSpeakerVolume(float volume);
00153                 float tuningGetEnergy(void);
00154                                 
00155                 // This returns true when it's safe to bring up the "device settings" dialog in the prefs.
00156                 // i.e. when the daemon is running and connected, and the device lists are populated.
00157                 bool deviceSettingsAvailable();
00158                 
00159                 // Requery the vivox daemon for the current list of input/output devices.
00160                 // If you pass true for clearCurrentList, deviceSettingsAvailable() will be false until the query has completed
00161                 // (use this if you want to know when it's done).
00162                 // 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.
00163                 void refreshDeviceLists(bool clearCurrentList = true);
00164                 
00165                 // Call this if the connection to the daemon terminates unexpectedly.  It will attempt to reset everything and relaunch.
00166                 void daemonDied();
00167 
00168                 // Call this if we're just giving up on voice (can't provision an account, etc.).  It will clean up and go away.
00169                 void giveUp();
00170                 
00172                 // Response/Event handlers
00173                 void connectorCreateResponse(int statusCode, std::string &statusString, std::string &connectorHandle);
00174                 void loginResponse(int statusCode, std::string &statusString, std::string &accountHandle);
00175                 void channelGetListResponse(int statusCode, std::string &statusString);
00176                 void sessionCreateResponse(int statusCode, std::string &statusString, std::string &sessionHandle);
00177                 void sessionConnectResponse(int statusCode, std::string &statusString);
00178                 void sessionTerminateResponse(int statusCode, std::string &statusString);
00179                 void logoutResponse(int statusCode, std::string &statusString);
00180                 void connectorShutdownResponse(int statusCode, std::string &statusString);
00181 
00182                 void loginStateChangeEvent(std::string &accountHandle, int statusCode, std::string &statusString, int state);
00183                 void sessionNewEvent(std::string &accountHandle, std::string &eventSessionHandle, int state, std::string &nameString, std::string &uriString);
00184                 void sessionStateChangeEvent(std::string &uriString, int statusCode, std::string &statusString, std::string &sessionHandle, int state,  bool isChannel, std::string &nameString);
00185                 void participantStateChangeEvent(std::string &uriString, int statusCode, std::string &statusString, int state,  std::string &nameString, std::string &displayNameString, int participantType);
00186                 void participantPropertiesEvent(std::string &uriString, int statusCode, std::string &statusString, bool isLocallyMuted, bool isModeratorMuted, bool isSpeaking, int volume, F32 energy);
00187                 void auxAudioPropertiesEvent(F32 energy);
00188         
00189                 void muteListChanged();
00190                 
00192                 // Sending updates of current state
00193                 void setCameraPosition(const LLVector3d &position, const LLVector3 &velocity, const LLMatrix3 &rot);
00194                 void setAvatarPosition(const LLVector3d &position, const LLVector3 &velocity, const LLMatrix3 &rot);
00195                 bool channelFromRegion(LLViewerRegion *region, std::string &name);
00196                 void leaveChannel(void);                // call this on logout or teleport begin
00197 
00198                 
00199                 void setMuteMic(bool muted);            // Use this to mute the local mic (for when the client is minimized, etc), ignoring user PTT state.
00200                 void setUserPTTState(bool ptt);
00201                 bool getUserPTTState();
00202                 void toggleUserPTTState(void);
00203                 void setVoiceEnabled(bool enabled);
00204                 static bool voiceEnabled();
00205                 void setUsePTT(bool usePTT);
00206                 void setPTTIsToggle(bool PTTIsToggle);
00207                 void setPTTKey(std::string &key);
00208                 void setEarLocation(S32 loc);
00209                 void setVoiceVolume(F32 volume);
00210                 void setMicGain(F32 volume);
00211                 void setUserVolume(const LLUUID& id, F32 volume); // set's volume for specified agent, from 0-1 (where .5 is nominal)
00212                 void setVivoxDebugServerName(std::string &serverName);
00213                 void setLipSyncEnabled(U32 enabled);
00214                 U32 lipSyncEnabled();
00215 
00216                 // PTT key triggering
00217                 void keyDown(KEY key, MASK mask);
00218                 void keyUp(KEY key, MASK mask);
00219                 void middleMouseState(bool down);
00220                 
00222                 // Accessors for data related to nearby speakers
00223                 BOOL getVoiceEnabled(const LLUUID& id);         // true if we've received data for this avatar
00224                 BOOL getIsSpeaking(const LLUUID& id);
00225                 BOOL getIsModeratorMuted(const LLUUID& id);
00226                 F32 getCurrentPower(const LLUUID& id);          // "power" is related to "amplitude" in a defined way.  I'm just not sure what the formula is...
00227                 BOOL getPTTPressed(const LLUUID& id);                   // This is the inverse of the "locally muted" property.
00228                 BOOL getOnMuteList(const LLUUID& id);
00229                 F32 getUserVolume(const LLUUID& id);
00230                 LLString getDisplayName(const LLUUID& id);
00231                 
00232                 // MBW -- XXX -- Not sure how to get this data out of the TVC
00233                 BOOL getUsingPTT(const LLUUID& id);
00234                 serviceType getServiceType(const LLUUID& id);   // type of chat the user is involved in (see bHear scope doc for definitions of A/B/C)
00235                 std::string getGroupID(const LLUUID& id);               // group ID if the user is in group chat (empty string if not applicable)
00236 
00238                 BOOL getAreaVoiceDisabled();            // returns true if the area the avatar is in is speech-disabled.
00239                                                                                         // Use this to determine whether to show a "no speech" icon in the menu bar.
00240 
00241                 struct participantState
00242                 {
00243                 public:
00244                         participantState(const std::string &uri);
00245                         std::string mURI;
00246                         std::string mName;
00247                         std::string mDisplayName;
00248                         bool mPTT;
00249                         bool mIsSpeaking;
00250                         bool mIsModeratorMuted;
00251                         LLFrameTimer mSpeakingTimeout;
00252                         F32     mLastSpokeTimestamp;
00253                         F32 mPower;
00254                         int mVolume;
00255                         serviceType mServiceType;
00256                         std::string mGroupID;
00257                         bool mOnMuteList;               // true if this avatar is on the user's mute list (and should be muted)
00258                         int mUserVolume;
00259                         bool mVolumeDirty;              // true if this participant needs a volume command sent (either mOnMuteList or mUserVolume has changed)
00260                         bool mAvatarIDValid;
00261                         LLUUID mAvatarID;
00262                 };
00263                 typedef std::map<std::string, participantState*> participantMap;
00264                 
00265                 participantState *findParticipant(const std::string &uri);
00266                 participantState *findParticipantByAvatar(LLVOAvatar *avatar);
00267                 participantState *findParticipantByID(const LLUUID& id);
00268                 
00269                 participantMap *getParticipantList(void);
00270 
00271                 void addObserver(LLVoiceClientParticipantObserver* observer);
00272                 void removeObserver(LLVoiceClientParticipantObserver* observer);
00273 
00274                 void addStatusObserver(LLVoiceClientStatusObserver* observer);
00275                 void removeStatusObserver(LLVoiceClientStatusObserver* observer);
00276                 
00277                 static void onAvatarNameLookup(const LLUUID& id, const char* first, const char* last, BOOL is_group, void* user_data);
00278                 typedef std::vector<std::string> deviceList;
00279 
00280                 deviceList *getCaptureDevices();
00281                 deviceList *getRenderDevices();
00282                 
00283                 void setNonSpatialChannel(
00284                         const std::string &uri,
00285                         const std::string &credentials);
00286                 void setSpatialChannel(
00287                         const std::string &uri,
00288                         const std::string &credentials);
00289                 void callUser(LLUUID &uuid);
00290                 void answerInvite(std::string &sessionHandle, LLUUID& other_user_id);
00291                 void declineInvite(std::string &sessionHandle);
00292                 void leaveNonSpatialChannel();
00293 
00294                 // Returns the URI of the current channel, or an empty string if not currently in a channel.
00295                 // NOTE that it will return an empty string if it's in the process of joining a channel.
00296                 std::string getCurrentChannel();
00297                 
00298                 // returns true iff the user is currently in a proximal (local spatial) channel.
00299                 // Note that gestures should only fire if this returns true.
00300                 bool inProximalChannel();
00301 
00302                 std::string sipURIFromID(const LLUUID &id);
00303 
00304         private:
00305 
00306                 // internal state for a simple state machine.  This is used to deal with the asynchronous nature of some of the messages.
00307                 // Note: if you change this list, please make corresponding changes to LLVoiceClient::state2string().
00308                 enum state
00309                 {
00310                         stateDisabled,                          // Voice is turned off.
00311                         stateStart,                                     // Class is initialized, socket is created
00312                         stateDaemonLaunched,            // Daemon has been launched
00313                         stateConnecting,                        // connect() call has been issued
00314                         stateIdle,                                      // socket is connected, ready for messaging
00315                         stateConnectorStart,            // connector needs to be started
00316                         stateConnectorStarting,         // waiting for connector handle
00317                         stateConnectorStarted,          // connector handle received
00318                         stateMicTuningNoLogin,          // mic tuning before login
00319                         stateLoginRetry,                        // need to retry login (failed due to changing password)
00320                         stateLoginRetryWait,            // waiting for retry timer
00321                         stateNeedsLogin,                        // send login request
00322                         stateLoggingIn,                         // waiting for account handle
00323                         stateLoggedIn,                          // account handle received
00324                         stateNoChannel,                         // 
00325                         stateMicTuningStart,
00326                         stateMicTuningRunning,          
00327                         stateMicTuningStop,
00328                         stateSessionCreate,                     // need to send Session.Create command
00329                         stateSessionConnect,            // need to send Session.Connect command
00330                         stateJoiningSession,            // waiting for session handle
00331                         stateSessionJoined,                     // session handle received
00332                         stateRunning,                           // in session, steady state
00333                         stateLeavingSession,            // waiting for terminate session response
00334                         stateSessionTerminated,         // waiting for terminate session response
00335 
00336                         stateLoggingOut,                        // waiting for logout response
00337                         stateLoggedOut,                         // logout response received
00338                         stateConnectorStopping,         // waiting for connector stop
00339                         stateConnectorStopped,          // connector stop received
00340                         
00341                         // We go to this state if the login fails because the account needs to be provisioned.
00342                         
00343                         // error states.  No way to recover from these yet.
00344                         stateConnectorFailed,
00345                         stateConnectorFailedWaiting,
00346                         stateLoginFailed,
00347                         stateLoginFailedWaiting,
00348                         stateJoinSessionFailed,
00349                         stateJoinSessionFailedWaiting,
00350 
00351                         stateJail                                       // Go here when all else has failed.  Nothing will be retried, we're done.
00352                 };
00353                 
00354                 state mState;
00355                 bool mSessionTerminateRequested;
00356                 bool mNonSpatialChannel;
00357                 
00358                 void setState(state inState);
00359                 state getState(void)  { return mState; };
00360                 static const char *state2string(state inState);
00361                 
00362                 void stateMachine();
00363                 static void idle(void *user_data);
00364                 
00365                 LLHost mDaemonHost;
00366                 LLSocket::ptr_t mSocket;
00367                 bool mConnected;
00368                 
00369                 void closeSocket(void);
00370                 
00371                 LLPumpIO *mPump;
00372                 friend class LLVivoxProtocolParser;
00373                 
00374                 std::string mAccountName;
00375                 std::string mAccountPassword;
00376                 std::string mAccountDisplayName;
00377                 std::string mAccountFirstName;
00378                 std::string mAccountLastName;
00379                 
00380                 std::string mNextP2PSessionURI;         // URI of the P2P session to join next
00381                 std::string mNextSessionURI;            // URI of the session to join next
00382                 std::string mNextSessionHandle;         // Session handle of the session to join next
00383                 std::string mNextSessionHash;           // Password hash for the session to join next
00384                 bool mNextSessionSpatial;                       // Will next session be a spatial chat?
00385                 bool mNextSessionNoReconnect;           // Next session should not auto-reconnect (i.e. user -> user chat)
00386                 bool mNextSessionResetOnClose;          // If this is true, go back to spatial chat when the next session terminates.
00387                 
00388                 std::string mSessionStateEventHandle;   // session handle received in SessionStateChangeEvents
00389                 std::string mSessionStateEventURI;              // session URI received in SessionStateChangeEvents
00390                 
00391                 bool mTuningMode;
00392                 float mTuningEnergy;
00393                 std::string mTuningAudioFile;
00394                 int mTuningMicVolume;
00395                 bool mTuningMicVolumeDirty;
00396                 int mTuningSpeakerVolume;
00397                 bool mTuningSpeakerVolumeDirty;
00398                 state mTuningExitState;                                 // state to return to when we leave tuning mode.
00399                 
00400                 std::string mSpatialSessionURI;
00401                 
00402                 bool mSessionResetOnClose;
00403                 
00404                 int mVivoxErrorStatusCode;              
00405                 std::string mVivoxErrorStatusString;
00406                 
00407                 std::string mChannelName;                       // Name of the channel to be looked up 
00408                 bool mAreaVoiceDisabled;
00409                 std::string mSessionURI;                        // URI of the session we're in.
00410                 bool mSessionP2P;                                       // true if this session is a p2p call
00411                 
00412                 S32 mCurrentParcelLocalID;                      // Used to detect parcel boundary crossings
00413                 std::string mCurrentRegionName;         // Used to detect parcel boundary crossings
00414                 
00415                 std::string mConnectorHandle;   // returned by "Create Connector" message
00416                 std::string mAccountHandle;             // returned by login message            
00417                 std::string mSessionHandle;             // returned by ?
00418                 U32 mCommandCookie;
00419         
00420                 std::string mAccountServerName;
00421                 std::string mAccountServerURI;
00422                 
00423                 int mLoginRetryCount;
00424                 
00425                 participantMap mParticipantMap;
00426                 bool mParticipantMapChanged;
00427                 
00428                 deviceList mCaptureDevices;
00429                 deviceList mRenderDevices;
00430 
00431                 std::string mCaptureDevice;
00432                 std::string mRenderDevice;
00433                 bool mCaptureDeviceDirty;
00434                 bool mRenderDeviceDirty;
00435                 
00436                 participantState *addParticipant(const std::string &uri);
00437                 // Note: after removeParticipant returns, the participant* that was passed to it will have been deleted.
00438                 // Take care not to use the pointer again after that.
00439                 void removeParticipant(participantState *participant);
00440                 void removeAllParticipants();
00441 
00442                 void updateMuteState(participantState *participant);
00443 
00444                 typedef std::map<std::string, std::string> channelMap;
00445                 channelMap mChannelMap;
00446                 
00447                 // These are used by the parser when processing a channel list response.
00448                 void clearChannelMap(void);
00449                 void addChannelMapEntry(std::string &name, std::string &uri);
00450                 std::string findChannelURI(std::string &name);
00451                         
00452                 // This should be called when the code detects we have changed parcels.
00453                 // It initiates the call to the server that gets the parcel channel.
00454                 void parcelChanged();
00455                 
00456         void switchChannel(std::string uri = std::string(), bool spatial = true, bool noReconnect = false, std::string hash = "");
00457                 void joinSession(std::string handle, std::string uri);
00458                 
00459                 std::string nameFromAvatar(LLVOAvatar *avatar);
00460                 std::string nameFromID(const LLUUID &id);
00461                 bool IDFromName(const std::string name, LLUUID &uuid);
00462                 std::string displayNameFromAvatar(LLVOAvatar *avatar);
00463                 std::string sipURIFromAvatar(LLVOAvatar *avatar);
00464                 std::string sipURIFromName(std::string &name);
00465                                 
00466                 void sendPositionalUpdate(void);
00467                 
00468                 void buildSetCaptureDevice(std::ostringstream &stream);
00469                 void buildSetRenderDevice(std::ostringstream &stream);
00470                 
00471                 void enforceTether(void);
00472                 
00473                 bool            mSpatialCoordsDirty;
00474                 
00475                 LLVector3d      mCameraPosition;
00476                 LLVector3d      mCameraRequestedPosition;
00477                 LLVector3       mCameraVelocity;
00478                 LLMatrix3       mCameraRot;
00479 
00480                 LLVector3d      mAvatarPosition;
00481                 LLVector3       mAvatarVelocity;
00482                 LLMatrix3       mAvatarRot;
00483                 
00484                 bool            mPTTDirty;
00485                 bool            mPTT;
00486                 
00487                 bool            mUsePTT;
00488                 bool            mPTTIsMiddleMouse;
00489                 KEY                     mPTTKey;
00490                 bool            mPTTIsToggle;
00491                 bool            mUserPTTState;
00492                 bool            mMuteMic;
00493                 
00494                 // Set to true when the mute state of someone in the participant list changes.
00495                 // The code will have to walk the list to find the changed participant(s).
00496                 bool            mVolumeDirty;
00497                 
00498                 enum
00499                 {
00500                         earLocCamera = 0,               // ear at camera
00501                         earLocAvatar,                   // ear at avatar
00502                         earLocMixed                             // ear at avatar location/camera direction
00503                 };
00504                 
00505                 S32                     mEarLocation;  
00506                 
00507                 bool            mSpeakerVolumeDirty;
00508                 bool            mSpeakerMuteDirty;
00509                 int                     mSpeakerVolume;
00510 
00511                 int                     mMicVolume;
00512                 bool            mMicVolumeDirty;
00513                 
00514                 bool            mVoiceEnabled;
00515                 bool            mWriteInProgress;
00516                 std::string mWriteString;
00517                 size_t          mWriteOffset;
00518                 
00519                 LLTimer         mUpdateTimer;
00520                 
00521                 U32                     mLipSyncEnabled;
00522 
00523                 typedef std::set<LLVoiceClientParticipantObserver*> observer_set_t;
00524                 observer_set_t mObservers;
00525 
00526                 void notifyObservers();
00527 
00528                 typedef std::set<LLVoiceClientStatusObserver*> status_observer_set_t;
00529                 status_observer_set_t mStatusObservers;
00530                 
00531                 void notifyStatusObservers(LLVoiceClientStatusObserver::EStatusType status);
00532 };
00533 
00534 extern LLVoiceClient *gVoiceClient;
00535 
00536 #endif //LL_VOICE_CLIENT_H
00537 
00538 
00539 

Generated on Fri May 16 08:34:22 2008 for SecondLife by  doxygen 1.5.5