llvoiceclient.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. /**
  2. * @file llvoiceclient.h
  3. * @brief Declaration of LLVoiceClient class.
  4. *
  5. * $LicenseInfo:firstyear=2007&license=viewergpl$
  6. *
  7. * Copyright (c) 2007-2009, Linden Research, Inc.
  8. * Copyright (c) 2009-2024, Henri Beauchamp.
  9. *
  10. * Second Life Viewer Source Code
  11. * The source code in this file ("Source Code") is provided by Linden Lab
  12. * to you under the terms of the GNU General Public License, version 2.0
  13. * ("GPL"), unless you have obtained a separate licensing agreement
  14. * ("Other License"), formally executed by you and Linden Lab. Terms of
  15. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  16. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  17. *
  18. * There are special exceptions to the terms and conditions of the GPL as
  19. * it is applied to this Source Code. View the full text of the exception
  20. * in the file doc/FLOSS-exception.txt in this software distribution, or
  21. * online at
  22. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  23. *
  24. * By copying, modifying or distributing this software, you acknowledge
  25. * that you have read and understood your obligations described above,
  26. * and agree to abide by those obligations.
  27. *
  28. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  29. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  30. * COMPLETENESS OR PERFORMANCE.
  31. * $/LicenseInfo$
  32. */
  33. #ifndef LL_LLVOICECLIENT_H
  34. #define LL_LLVOICECLIENT_H
  35. #include "boost/signals2.hpp"
  36. #include "lluuid.h"
  37. class LLPumpIO;
  38. constexpr F32 OVERDRIVEN_POWER_LEVEL = 0.7f;
  39. class LLVoiceClientStatusObserver
  40. {
  41. public:
  42. typedef enum e_voice_status_type
  43. {
  44. // NOTE: when updating this enum, please also update the switch in
  45. // LLVoiceClientStatusObserver::status2string().
  46. STATUS_LOGIN_RETRY,
  47. STATUS_LOGGED_IN,
  48. STATUS_JOINING,
  49. STATUS_JOINED,
  50. STATUS_LEFT_CHANNEL,
  51. STATUS_VOICE_DISABLED,
  52. STATUS_VOICE_ENABLED,
  53. BEGIN_ERROR_STATUS,
  54. ERROR_CHANNEL_FULL,
  55. ERROR_CHANNEL_LOCKED,
  56. ERROR_NOT_AVAILABLE,
  57. ERROR_UNKNOWN
  58. } EStatusType;
  59. virtual ~LLVoiceClientStatusObserver() = default;
  60. virtual void onChange(EStatusType status, const LLSD& channel_info,
  61. bool proximal) = 0;
  62. static std::string status2string(EStatusType inStatus);
  63. };
  64. // Purely virtual class, used *only* for the few methods which are both common
  65. // to all voice modules *and* get called by LLVoiceClient via module pointers:
  66. // this is a *minimal* common API to avoid pointlessly virtual methods and
  67. // their costlier calls. HB
  68. class LLVoiceModule
  69. {
  70. friend class LLVoiceClient;
  71. public:
  72. LLVoiceModule() = default;
  73. virtual ~LLVoiceModule() = default;
  74. // Module identification
  75. virtual bool isVivox() const = 0;
  76. virtual bool isWebRTC() const = 0;
  77. virtual const std::string& getName() const = 0;
  78. // Channels related methods
  79. virtual bool inProximalChannel() const = 0;
  80. virtual void setSpatialChannel(const LLSD& channel_info) = 0;
  81. virtual void setNonSpatialChannel(const LLSD& channel_info,
  82. bool notify_on_first_join,
  83. bool hangup_on_last_leave) = 0;
  84. virtual void leaveNonSpatialChannel() = 0;
  85. virtual void leaveAudioSession() = 0;
  86. virtual void processChannels(bool enabled) = 0;
  87. virtual std::string sipURIFromID(const LLUUID& id) const = 0;
  88. #if 0 // Not yet used by the Cool VL Viewer. *TODO: implement ? HB
  89. virtual void setHidden(bool b) const = 0;
  90. protected:
  91. bool mHidden = false;
  92. #endif
  93. };
  94. class LLVoiceClient
  95. {
  96. friend class LLVivoxProtocolParser;
  97. friend class LLVoiceVivox;
  98. protected:
  99. LOG_CLASS(LLVoiceClient);
  100. public:
  101. LLVoiceClient();
  102. ~LLVoiceClient();
  103. LL_INLINE bool ready() { return mReady; }
  104. // Call after loading settings and whenever they change
  105. void updateSettings();
  106. // Methods used in llfloatervoicedevicesettings.cpp
  107. void setCaptureDevice(const std::string& device_id, bool webrtc);
  108. void setRenderDevice(const std::string& device_id, bool webrtc);
  109. typedef std::map<std::string, std::string> device_map_t;
  110. const device_map_t& getCaptureDevices(bool webrtc) const;
  111. const device_map_t& getRenderDevices(bool webrtc) const;
  112. void tuningStart(bool webrtc);
  113. void tuningStop(bool webrtc);
  114. bool inTuningMode(bool webrtc);
  115. // This method auto-determines which of Vivox or WebRTC is in use. HB
  116. bool tuningModeActive();
  117. void tuningSetMicVolume(F32 volume, bool webrtc);
  118. #if 0 // Not used
  119. void tuningSetSpeakerVolume(F32 volume, bool webrtc);
  120. #endif
  121. F32 tuningGetEnergy(bool webrtc);
  122. // This returns true when it is safe to bring up the "device settings"
  123. // dialog in the prefs. I.e. when the daemon is running and connected, and
  124. // the device lists are populated.
  125. bool deviceSettingsAvailable(bool webrtc);
  126. // Requery the voice engine for the current list of input/output devices.
  127. // If you pass true for clear_current_list, deviceSettingsAvailable() will
  128. // be false until the query has completed (use this if you want to know
  129. // when it is done). If you pass false, you will have no way to know when
  130. // the query finishes, but the device lists will not appear empty in the
  131. // interim.
  132. void refreshDeviceLists(bool clear_current_list, bool webrtc);
  133. /////////////////////////////
  134. // Sending updates of current state
  135. // Use this to mute the local mic (for when the client is minimized, etc),
  136. // ignoring user PTT state. Used from llvieweraudio.cpp.
  137. LL_INLINE void setMuteMic(bool muted) { mMuteMic = muted; }
  138. // Used from llvieweraudio.cpp
  139. void setVoiceVolume(F32 volume);
  140. void setMicGain(F32 volume);
  141. // Used from llfloateractivespeakers.cpp and llfloaterim.cpp
  142. F32 getUserVolume(const LLUUID& id);
  143. // Sets volume for specified agent, from 0-1 (where .5 is nominal)
  144. void setUserVolume(const LLUUID& id, F32 volume);
  145. // Used from llvoiceremotectrl.cpp
  146. LL_INLINE void setUserPTTState(bool ptt) { mUserPTTState = ptt; }
  147. LL_INLINE bool getUserPTTState() const { return mUserPTTState; }
  148. LL_INLINE void toggleUserPTTState() { mUserPTTState = !mUserPTTState; }
  149. bool isAgentMicOpen() const;
  150. void setUsePTT(bool use_it);
  151. void setPTTIsToggle(bool set_as_toggle);
  152. LL_INLINE bool getPTTIsToggle() const { return mPTTIsToggle; }
  153. bool setPTTKey(const std::string& key);
  154. void setEarLocation(S32 loc);
  155. // PTT key triggering. Used from llviewerwindow.cpp
  156. void keyDown(KEY key, MASK mask);
  157. void keyUp(KEY key, MASK mask);
  158. void inputUserControlState(bool down);
  159. void middleMouseState(bool down);
  160. /////////////////////////////
  161. // Accessors for data related to nearby speakers
  162. // Used from llfloateractivespeakers.cpp and llvoavatar.cpp
  163. bool getIsSpeaking(const LLUUID& id);
  164. // true if we have received data for this avatar.
  165. bool getVoiceEnabled(const LLUUID& id);
  166. // "power" is related to "amplitude" in a defined way. I'm just not sure
  167. // what the formula is...
  168. F32 getCurrentPower(const LLUUID& id);
  169. // Used from llfloateractivespeakers.cpp
  170. bool getIsModeratorMuted(const LLUUID& id);
  171. bool getOnMuteList(const LLUUID& id);
  172. // This is used by the string-keyed maps below, to avoid storing the string
  173. // twice. The 'const std::string*' in the key points to a string actually
  174. // stored in the object referenced by the map. The add & delete operations
  175. // for each map allocate and delete in the right order to avoid dangling
  176. // references. The default compare operation would just compare pointers,
  177. // which is incorrect, so they must use this comparator instead.
  178. struct stringMapComparator
  179. {
  180. LL_INLINE bool operator()(const std::string* a,
  181. const std::string* b) const
  182. {
  183. return a->compare(*b) < 0;
  184. }
  185. };
  186. struct uuidMapComparator
  187. {
  188. LL_INLINE bool operator()(const LLUUID* a, const LLUUID* b) const
  189. {
  190. return *a < *b;
  191. }
  192. };
  193. // Used in llfloateractivespeakers.cpp
  194. struct ParticipantData
  195. {
  196. LL_INLINE ParticipantData(const LLUUID& id, const std::string& name,
  197. bool avatar)
  198. : mId(id),
  199. mName(name),
  200. mIsAvatar(avatar)
  201. {
  202. }
  203. LLUUID mId;
  204. std::string mName;
  205. bool mIsAvatar;
  206. };
  207. typedef std::vector<ParticipantData> participants_vec_t;
  208. bool getParticipants(participants_vec_t& participants);
  209. void setVoiceEnabled(bool enabled);
  210. // Called from llstartup.cpp
  211. void userAuthorized(const std::string& first_name,
  212. const std::string& last_name, const LLUUID& agent_id);
  213. // Used by llvoicechannel.cpp
  214. void addObserver(LLVoiceClientStatusObserver* observerp);
  215. void removeObserver(LLVoiceClientStatusObserver* observerp);
  216. void setNonSpatialChannel(const LLSD& channel_info,
  217. bool notify_on_first_join,
  218. bool hangup_on_last_leave);
  219. void leaveNonSpatialChannel();
  220. void activateSpatialChannel(bool activate);
  221. bool isCurrentChannel(const LLSD& channel_info);
  222. bool compareChannels(const LLSD& channel_info1, const LLSD& channel_info2);
  223. // Starts a voice session with the specified user using the specified type
  224. // of server.
  225. void callUser(const LLUUID& id, U32 server_type);
  226. // End the session using the specified type of server.
  227. void hangup(U32 server_type);
  228. std::string sipURIFromID(const LLUUID& id) const;
  229. // Used by LLViewerParcelVoiceInfo
  230. void setSpatialChannel(const LLSD& channel_info);
  231. // Called from llfloaterim.cpp
  232. // Called from llimmgr.cpp
  233. void declineInvite(const LLSD& channel_info);
  234. // Called from llvoicechannel.cpp
  235. bool answerInvite(const LLSD& channel_info);
  236. // Called from llfloateractivespeakers.cpp, llvoavatar.cpp and
  237. // llvoicechannel.cpp
  238. // Returns true iff the user is currently in a proximal (local spatial)
  239. // channel. Note that gestures should only fire if this returns true.
  240. bool inProximalChannel() const;
  241. // Called once from llappviewer.cpp at application startup (creates
  242. // the connector)
  243. void init(LLPumpIO* pumpp);
  244. // Called from llappviewer.cpp to clean up during shutdown
  245. void terminate();
  246. // Called from LLAgent::handleServerFeaturesTransition(). HB
  247. void handleSimFeaturesReceived(const LLSD& features);
  248. bool isVoiceWorking();
  249. // Called from various places in the viewer
  250. static bool voiceEnabled();
  251. // Used by llimmgr.cpp and llvoicechannel.cpp, so that we do not need to
  252. // deal with module pointers there... HB
  253. enum e_server_type : U32
  254. {
  255. UNKNOWN_SERVER,
  256. VIVOX_SERVER,
  257. WEBRTC_SERVER,
  258. };
  259. // Returns the type of server as defined above. HB
  260. U32 getVoiceServerType(const LLSD& channel_info);
  261. LLVoiceModule* getModuleFromType(const std::string& server_type);
  262. LLVoiceModule* getModuleFromChannelInfo(const LLSD& channel_info);
  263. private:
  264. static LLVoiceModule* getModuleFromSimFeatures(const LLSD& features,
  265. bool save = false);
  266. void setSpatialVoiceModule(LLVoiceModule* modulep);
  267. void setNonSpatialVoiceModule(LLVoiceModule* modulep);
  268. void onParcelChange();
  269. private:
  270. // Used to store spatial credentials for Vivox so they are available when
  271. // the region voice server is retrieved.
  272. LLSD mSpatialCredentials;
  273. LLVoiceModule* mSpatialVoiceModulep;
  274. LLVoiceModule* mNonSpatialVoiceModulep;
  275. typedef boost::signals2::connection connection_t;
  276. connection_t mParcelChangedConnection;
  277. KEY mPTTKey;
  278. bool mUsePTT;
  279. bool mPTTIsMiddleMouse;
  280. bool mPTTIsToggle;
  281. bool mUserPTTState;
  282. bool mMuteMic;
  283. bool mReady;
  284. };
  285. // Note: since this is a global class instance, all class members are always
  286. // available, from viewer launch to _exit(): no need for static variables to
  287. // track the shutdown (or ready) state ! HB
  288. extern LLVoiceClient gVoiceClient;
  289. #endif //LL_LLVOICECLIENT_H