From 0f61c00218a07a7d487e33256382c4a10561e0c1 Mon Sep 17 00:00:00 2001 From: Aimee Linden Date: Mon, 22 Feb 2010 16:50:46 +0000 Subject: Enumerate available voice fonts. --- indra/newview/llvoiceclient.cpp | 124 ++++++++++++++++++++++++++++++++++++++++ indra/newview/llvoiceclient.h | 38 ++++++++++-- 2 files changed, 158 insertions(+), 4 deletions(-) (limited to 'indra') diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 59606f17b2..92dfa6d30e 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -240,6 +240,12 @@ protected: std::string audioMediaString; std::string displayNameString; std::string deviceString; + std::string idString; + std::string descriptionString; + std::string expirationDateString; + bool hasExpired; + std::string fontTypeString; + std::string fontStatusString; int participantType; bool isLocallyMuted; bool isModeratorMuted; @@ -625,6 +631,34 @@ void LLVivoxProtocolParser::EndTag(const char *tag) autoAcceptMask = string; else if (!stricmp("AutoAddAsBuddy", tag)) autoAddAsBuddy = string; + else if (!stricmp("SessionFont", tag)) + { + gVoiceClient->addSessionFont(idString, nameString, descriptionString, expirationDateString, hasExpired, fontTypeString, fontStatusString); + } + else if (!stricmp("ID", tag)) + { + idString = string; + } + else if (!stricmp("Description", tag)) + { + descriptionString = string; + } + else if (!stricmp("ExpirationDate", tag)) + { + expirationDateString = string; + } + else if (!stricmp("Expired", tag)) + { + hasExpired = !stricmp(string.c_str(), "1"); + } + else if (!stricmp("Type", tag)) + { + fontTypeString = string; + } + else if (!stricmp("Status", tag)) + { + fontStatusString = string; + } else if (!stricmp("MessageHeader", tag)) messageHeader = string; else if (!stricmp("MessageBody", tag)) @@ -895,6 +929,10 @@ void LLVivoxProtocolParser::processResponse(std::string tag) { gVoiceClient->accountListAutoAcceptRulesResponse(statusCode, statusString); } + else if (!stricmp(actionCstr, "Account.GetSessionFonts.1")) + { + gVoiceClient->accountGetSessionFontsResponse(statusCode, statusString); + } else if (!stricmp(actionCstr, "Session.Set3DPosition.1")) { // We don't need to process these, but they're so spammy we don't want to log them. @@ -1243,6 +1281,9 @@ LLVoiceClient::LLVoiceClient() : mBuddyListMapPopulated(false), mBlockRulesListReceived(false), mAutoAcceptRulesListReceived(false), + + mSessionFontsReceived(false), + mCaptureDeviceDirty(false), mRenderDeviceDirty(false), mSpatialCoordsDirty(false), @@ -2156,6 +2197,9 @@ void LLVoiceClient::stateMachine() notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LOGGED_IN); + // request the set of available voice fonts + accountGetSessionFontsSendMessage(); + // request the current set of block rules (we'll need them when updating the friends list) accountListBlockRulesSendMessage(); @@ -2641,6 +2685,24 @@ void LLVoiceClient::accountListAutoAcceptRulesSendMessage() } } +void LLVoiceClient::accountGetSessionFontsSendMessage() +{ + if(!mAccountHandle.empty()) + { + std::ostringstream stream; + + LL_DEBUGS("Voice") << "requesting session font list" << LL_ENDL; + + stream + << "" + << "" << mAccountHandle << "" + << "" + << "\n\n\n"; + + writeString(stream.str()); + } +} + void LLVoiceClient::sessionGroupCreateSendMessage() { if(!mAccountHandle.empty()) @@ -2691,6 +2753,7 @@ void LLVoiceClient::sessionCreateSendMessage(sessionState *session, bool startAu stream << "" << (startAudio?"true":"false") << "" << "" << (startText?"true":"false") << "" +// << "0" << "" << mChannelName << "" << "\n\n\n"; writeString(stream.str()); @@ -2766,6 +2829,21 @@ void LLVoiceClient::sessionTextConnectSendMessage(sessionState *session) writeString(stream.str()); } +void LLVoiceClient::sessionSetVoiceFontSendMessage(sessionState *session, const std::string &fontId) +{ + LL_DEBUGS("Voice") << "selecting voice font: " << fontId << " in session handle: " << session->mHandle << LL_ENDL; + + std::ostringstream stream; + + stream + << "" + << "" << session->mHandle << "" + << "" << fontId << "" + << "\n\n\n"; + + writeString(stream.str()); +} + void LLVoiceClient::sessionTerminate() { mSessionTerminateRequested = true; @@ -6958,6 +7036,46 @@ void LLVoiceClient::addAutoAcceptRule(const std::string &autoAcceptMask, const s } } +LLVoiceClient::voiceFontEntry::voiceFontEntry(const std::string &id) : + mID(id), + mHasExpired(false) +{ +} + +LLVoiceClient::voiceFontEntry *LLVoiceClient::addSessionFont(const std::string &id, + const std::string &name, + const std::string &description, + const std::string &expirationDate, + const bool hasExpired, + const std::string &fontType, + const std::string &fontStatus) +{ + voiceFontEntry *font = NULL; + + voiceFontMap::iterator iter = mSessionFontMap.find(&id); + if(iter != mSessionFontMap.end()) + { + // Found session font already in the map. + LL_DEBUGS("Voice") << "existing session font " << id << " : " << name << LL_ENDL; + font = iter->second; + } + + if(font == NULL) + { + LL_DEBUGS("Voice") << "adding session font " << id << " : " << name << (hasExpired?" (Expired)":"") << LL_ENDL; + font = new voiceFontEntry(id); + font->mName = name; + font->mDescription = description; + font->mExpirationDate = expirationDate; + font->mHasExpired = hasExpired; + font->mFontType = fontType; + font->mFontStatus = fontStatus; + + mSessionFontMap.insert(voiceFontMap::value_type(&(font->mID), font)); + } + return font; +} + void LLVoiceClient::accountListBlockRulesResponse(int statusCode, const std::string &statusString) { // Block list entries were updated via addBlockRule() during parsing. Just flag that we're done. @@ -6970,6 +7088,12 @@ void LLVoiceClient::accountListAutoAcceptRulesResponse(int statusCode, const std mAutoAcceptRulesListReceived = true; } +void LLVoiceClient::accountGetSessionFontsResponse(int statusCode, const std::string &statusString) +{ + // Session font list entries were updated via addSessionFont() during parsing. Just flag that we're done. + mSessionFontsReceived = true; +} + void LLVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer) { mParticipantObservers.insert(observer); diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index a96cf18e27..05624bcefd 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -424,8 +424,32 @@ static void updatePosition(void); void deleteAllAutoAcceptRules(void); void addAutoAcceptRule(const std::string &autoAcceptMask, const std::string &autoAddAsBuddy); void accountListBlockRulesResponse(int statusCode, const std::string &statusString); - void accountListAutoAcceptRulesResponse(int statusCode, const std::string &statusString); - + void accountListAutoAcceptRulesResponse(int statusCode, const std::string &statusString); + + struct voiceFontEntry + { + voiceFontEntry(const std::string &id); + // *TODO: Decide which of these we don't need to store + std::string mID; + std::string mName; + std::string mDescription; + std::string mExpirationDate; + bool mHasExpired; + std::string mFontType; + std::string mFontStatus; + }; + + typedef std::map voiceFontMap; + + voiceFontEntry *addSessionFont(const std::string &id, + const std::string &name, + const std::string &description, + const std::string &expirationDate, + const bool hasExpired, + const std::string &fontType, + const std::string &fontStatus); + void accountGetSessionFontsResponse(int statusCode, const std::string &statusString); + ///////////////////////////// // session control messages void connectorCreate(); @@ -447,12 +471,15 @@ static void updatePosition(void); void accountListBlockRulesSendMessage(); void accountListAutoAcceptRulesSendMessage(); - + + void accountGetSessionFontsSendMessage(); + void sessionGroupCreateSendMessage(); void sessionCreateSendMessage(sessionState *session, bool startAudio = true, bool startText = false); void sessionGroupAddSessionSendMessage(sessionState *session, bool startAudio = true, bool startText = false); void sessionMediaConnectSendMessage(sessionState *session); // just joins the audio session void sessionTextConnectSendMessage(sessionState *session); // just joins the text session + void sessionSetVoiceFontSendMessage(sessionState *session, const std::string &fontId); void sessionTerminateSendMessage(sessionState *session); void sessionGroupTerminateSendMessage(sessionState *session); void sessionMediaDisconnectSendMessage(sessionState *session); @@ -653,7 +680,10 @@ static void updatePosition(void); bool mBlockRulesListReceived; bool mAutoAcceptRulesListReceived; buddyListMap mBuddyListMap; - + + bool mSessionFontsReceived; + voiceFontMap mSessionFontMap; + deviceList mCaptureDevices; deviceList mRenderDevices; -- cgit v1.2.3 From 5518e15f89359ba1627633f59f7299b69fc2bd69 Mon Sep 17 00:00:00 2001 From: Aimee Linden Date: Mon, 22 Feb 2010 16:52:23 +0000 Subject: Added stateFontListReceived to the voice client state machine. This makes sure we have the voice font list before attempting to start a session. --- indra/newview/llvoiceclient.cpp | 11 +++++++++++ indra/newview/llvoiceclient.h | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 92dfa6d30e..de4e53f52c 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -1622,6 +1622,7 @@ std::string LLVoiceClient::state2string(LLVoiceClient::state inState) CASE(stateNeedsLogin); CASE(stateLoggingIn); CASE(stateLoggedIn); + CASE(stateFontListReceived); CASE(stateCreatingSessionGroup); CASE(stateNoChannel); CASE(stateJoiningSession); @@ -2231,6 +2232,11 @@ void LLVoiceClient::stateMachine() writeString(stream.str()); } } + + // accountGetSessionFontsResponse() will transition from here to stateFontListReceived. + + //MARK: stateFontListReceived + case stateFontListReceived: // font list received #if USE_SESSION_GROUPS // create the main session group @@ -7092,6 +7098,11 @@ void LLVoiceClient::accountGetSessionFontsResponse(int statusCode, const std::st { // Session font list entries were updated via addSessionFont() during parsing. Just flag that we're done. mSessionFontsReceived = true; + + if(getState() == stateLoggedIn) + { + setState(stateFontListReceived); + } } void LLVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer) diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 05624bcefd..2d8fff5508 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -429,7 +429,6 @@ static void updatePosition(void); struct voiceFontEntry { voiceFontEntry(const std::string &id); - // *TODO: Decide which of these we don't need to store std::string mID; std::string mName; std::string mDescription; @@ -584,6 +583,7 @@ static void updatePosition(void); stateNeedsLogin, // send login request stateLoggingIn, // waiting for account handle stateLoggedIn, // account handle received + stateFontListReceived, // List of available voice fonts received stateCreatingSessionGroup, // Creating the main session group stateNoChannel, // stateJoiningSession, // waiting for session handle -- cgit v1.2.3 From 9f9b240dcee53a50b56a0ccb8d255a86d0ce62c9 Mon Sep 17 00:00:00 2001 From: Aimee Linden Date: Tue, 6 Apr 2010 11:39:01 +0100 Subject: Added voice font selection to the voice floater. --- indra/newview/app_settings/logcontrol.xml | 1 + indra/newview/llcallfloater.cpp | 53 ++++++++++++++-- indra/newview/llcallfloater.h | 21 ++++--- indra/newview/llvoiceclient.cpp | 73 +++++++++++++++++----- indra/newview/llvoiceclient.h | 23 ++++--- .../default/xui/en/floater_voice_controls.xml | 38 ++++++++++- 6 files changed, 173 insertions(+), 36 deletions(-) (limited to 'indra') diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index d7bb64ce8a..d3fb958638 100644 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml @@ -40,6 +40,7 @@ tags + Voice diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index 76e058a1c3..52739184c0 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -52,6 +52,7 @@ #include "lltransientfloatermgr.h" #include "llviewerwindow.h" #include "llvoicechannel.h" +#include "llvoiceclient.h" // for Voice font list types #include "llviewerparcelmgr.h" static void get_voice_participants_uuids(std::vector& speakers_uuids); @@ -95,7 +96,7 @@ static void* create_non_avatar_caller(void*) return new LLNonAvatarCaller; } -LLVoiceChannel* LLCallFloater::sCurrentVoiceCanel = NULL; +LLVoiceChannel* LLCallFloater::sCurrentVoiceChannel = NULL; LLCallFloater::LLCallFloater(const LLSD& key) : LLTransientDockableFloater(NULL, false, key) @@ -105,6 +106,7 @@ LLCallFloater::LLCallFloater(const LLSD& key) , mNonAvatarCaller(NULL) , mVoiceType(VC_LOCAL_CHAT) , mAgentPanel(NULL) +, mVoiceFont(NULL) , mSpeakingIndicator(NULL) , mIsModeratorMutedVoice(false) , mInitParticipantsVoiceState(false) @@ -146,6 +148,9 @@ BOOL LLCallFloater::postBuild() childSetAction("leave_call_btn", boost::bind(&LLCallFloater::leaveCall, this)); + mVoiceFont = getChild("voice_font"); + childSetCommitCallback("voice_font", commitVoiceFont, this); // *FIX: childSetCommitCallback deprecated + mNonAvatarCaller = getChild("non_avatar_caller"); mNonAvatarCaller->setVisible(FALSE); @@ -157,7 +162,6 @@ BOOL LLCallFloater::postBuild() initAgentData(); - connectToChannel(LLVoiceChannel::getCurrentVoiceChannel()); setIsChrome(true); @@ -205,6 +209,9 @@ void LLCallFloater::draw() // virtual void LLCallFloater::onChange() { + // *FIX: Temporarily dumping this here till I decide where it should go + updateVoiceFont(); + if (NULL == mParticipants) return; updateParticipantsVoiceState(); @@ -231,6 +238,37 @@ void LLCallFloater::leaveCall() } } +/* static */ +void LLCallFloater::commitVoiceFont(LLUICtrl* ctrl, void* userdata) +{ + LLVoiceClient::getInstance()->setVoiceFont(ctrl->getValue()); +} + +void LLCallFloater::updateVoiceFont() +{ + if (mVoiceFont) + { + mVoiceFont->removeall(); + mVoiceFont->add(getString("no_voice_font"), 0); + + if (LLVoiceClient::getInstance()->getVoiceFontsAvailable()) + { + const LLVoiceClient::voice_font_list_t font_list = LLVoiceClient::getInstance()->getVoiceFontList(); + + for (LLVoiceClient::voice_font_list_t::const_iterator it = font_list.begin(); it != font_list.end(); ++it) + { + mVoiceFont->add(*(it->second), it->first, ADD_BOTTOM); + } + mVoiceFont->setEnabled(true); + mVoiceFont->setValue(LLVoiceClient::getInstance()->getVoiceFont()); + } + else + { + mVoiceFont->setEnabled(false); + } + } +} + void LLCallFloater::updateSession() { LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel(); @@ -369,7 +407,7 @@ void LLCallFloater::sOnCurrentChannelChanged(const LLUUID& /*session_id*/) // *NOTE: if signal was sent for voice channel with LLVoiceChannel::STATE_NO_CHANNEL_INFO // it sill be sent for the same channel again (when state is changed). // So, lets ignore this call. - if (channel == sCurrentVoiceCanel) return; + if (channel == sCurrentVoiceChannel) return; LLCallFloater* call_floater = LLFloaterReg::getTypedInstance("voice_controls"); @@ -714,9 +752,9 @@ void LLCallFloater::connectToChannel(LLVoiceChannel* channel) { mVoiceChannelStateChangeConnection.disconnect(); - sCurrentVoiceCanel = channel; + sCurrentVoiceChannel = channel; - mVoiceChannelStateChangeConnection = sCurrentVoiceCanel->setStateChangedCallback(boost::bind(&LLCallFloater::onVoiceChannelStateChanged, this, _1, _2)); + mVoiceChannelStateChangeConnection = sCurrentVoiceChannel->setStateChangedCallback(boost::bind(&LLCallFloater::onVoiceChannelStateChanged, this, _1, _2)); updateState(channel->getState()); } @@ -736,7 +774,7 @@ void LLCallFloater::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old void LLCallFloater::updateState(const LLVoiceChannel::EState& new_state) { - LL_DEBUGS("Voice") << "Updating state: " << new_state << ", session name: " << sCurrentVoiceCanel->getSessionName() << LL_ENDL; + LL_DEBUGS("Voice") << "Updating state: " << new_state << ", session name: " << sCurrentVoiceChannel->getSessionName() << LL_ENDL; if (LLVoiceChannel::STATE_CONNECTED == new_state) { updateSession(); @@ -745,6 +783,9 @@ void LLCallFloater::updateState(const LLVoiceChannel::EState& new_state) { reset(new_state); } + + // *FIX: Dumped here till I decide where to put it + updateVoiceFont(); } void LLCallFloater::reset(const LLVoiceChannel::EState& new_state) diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h index 0a8ea7de39..9a13d853c9 100644 --- a/indra/newview/llcallfloater.h +++ b/indra/newview/llcallfloater.h @@ -40,6 +40,7 @@ class LLAvatarList; class LLAvatarListItem; +class LLComboBox; class LLNonAvatarCaller; class LLOutputMonitorCtrl; class LLParticipantList; @@ -47,15 +48,15 @@ class LLSpeakerMgr; class LLSpeakersDelayActionsStorage; /** - * The Voice Control Panel is an ambient window summoned by clicking the flyout chevron on the Speak button. - * It can be torn-off and freely positioned onscreen. + * The Voice Control Panel is an ambient window summoned by clicking the flyout chevron + * on the Speak button. It can be torn-off and freely positioned onscreen. * - * When the Resident is engaged in Nearby Voice Chat, the Voice Control Panel provides control over - * the Resident's own microphone input volume, the audible volume of each of the other participants, - * the Resident's own Voice Morphing settings (if she has subscribed to enable the feature), and Voice Recording. + * When the Resident is engaged in Voice Chat, the Voice Control Panel provides control + * over the audible volume of each of the other participants, the Resident's own Voice + * Morphing settings (if she has subscribed to enable the feature), and Voice Recording. * - * When the Resident is engaged in any chat except Nearby Chat, the Voice Control Panel also provides an - * 'Leave Call' button to allow the Resident to leave that voice channel. + * When the Resident is engaged in any chat except Nearby Chat, the Voice Control Panel + * also provides a 'Leave Call' button to allow the Resident to leave that voice channel. */ class LLCallFloater : public LLTransientDockableFloater, LLVoiceClientParticipantObserver { @@ -101,6 +102,9 @@ private: void leaveCall(); + static void commitVoiceFont(LLUICtrl*,void* userdata); + void updateVoiceFont(); + /** * Updates mSpeakerManager and list according to current Voice Channel * @@ -230,6 +234,7 @@ private: LLNonAvatarCaller* mNonAvatarCaller; EVoiceControls mVoiceType; LLPanel* mAgentPanel; + LLComboBox* mVoiceFont; LLOutputMonitorCtrl* mSpeakingIndicator; bool mIsModeratorMutedVoice; @@ -259,7 +264,7 @@ private: * * @see sOnCurrentChannelChanged() */ - static LLVoiceChannel* sCurrentVoiceCanel; + static LLVoiceChannel* sCurrentVoiceChannel; /* virtual */ LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; } diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index de4e53f52c..5502744882 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -240,7 +240,7 @@ protected: std::string audioMediaString; std::string displayNameString; std::string deviceString; - std::string idString; + S32 id; std::string descriptionString; std::string expirationDateString; bool hasExpired; @@ -503,7 +503,20 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr) { gVoiceClient->deleteAllAutoAcceptRules(); } - + else if (!stricmp("SessionFonts", tag)) + { + LLVoiceClient::getInstance()->clearSessionFonts(); + } + else if (!stricmp("SessionFont", tag)) + { + id = 0; + nameString.clear(); + descriptionString.clear(); + expirationDateString.clear(); + hasExpired.clear(); + fontTypeString.clear(); + fontStatusString.clear(); + } } } responseDepth++; @@ -633,11 +646,11 @@ void LLVivoxProtocolParser::EndTag(const char *tag) autoAddAsBuddy = string; else if (!stricmp("SessionFont", tag)) { - gVoiceClient->addSessionFont(idString, nameString, descriptionString, expirationDateString, hasExpired, fontTypeString, fontStatusString); + LLVoiceClient::getInstance()->addSessionFont(id, nameString, descriptionString, expirationDateString, hasExpired, fontTypeString, fontStatusString); } else if (!stricmp("ID", tag)) { - idString = string; + id = strtol(string.c_str(), NULL, 10); } else if (!stricmp("Description", tag)) { @@ -860,6 +873,8 @@ void LLVivoxProtocolParser::processResponse(std::string tag) } else if (!stricmp(eventTypeCstr, "SessionUpdatedEvent")) { + // *TODO: Receive the current SessionFontID? + /* c1_m1000xFnPP04IpREWNkuw1cOXlhw==_sg0 @@ -931,7 +946,7 @@ void LLVivoxProtocolParser::processResponse(std::string tag) } else if (!stricmp(actionCstr, "Account.GetSessionFonts.1")) { - gVoiceClient->accountGetSessionFontsResponse(statusCode, statusString); + LLVoiceClient::getInstance()->accountGetSessionFontsResponse(statusCode, statusString); } else if (!stricmp(actionCstr, "Session.Set3DPosition.1")) { @@ -1283,6 +1298,7 @@ LLVoiceClient::LLVoiceClient() : mAutoAcceptRulesListReceived(false), mSessionFontsReceived(false), + mFontID(0), mCaptureDeviceDirty(false), mRenderDeviceDirty(false), @@ -2759,7 +2775,7 @@ void LLVoiceClient::sessionCreateSendMessage(sessionState *session, bool startAu stream << "" << (startAudio?"true":"false") << "" << "" << (startText?"true":"false") << "" -// << "0" + << "" << mFontID << "" << "" << mChannelName << "" << "\n\n\n"; writeString(stream.str()); @@ -2835,16 +2851,17 @@ void LLVoiceClient::sessionTextConnectSendMessage(sessionState *session) writeString(stream.str()); } -void LLVoiceClient::sessionSetVoiceFontSendMessage(sessionState *session, const std::string &fontId) +void LLVoiceClient::sessionSetVoiceFontSendMessage(sessionState *session) { - LL_DEBUGS("Voice") << "selecting voice font: " << fontId << " in session handle: " << session->mHandle << LL_ENDL; + llassert(session); + LL_DEBUGS("Voice") << "requesting voice font: " << mFontID << " in session handle: " << session->mHandle << LL_ENDL; std::ostringstream stream; stream - << "" + << "" << "" << session->mHandle << "" - << "" << fontId << "" + << "" << mFontID << "" << "\n\n\n"; writeString(stream.str()); @@ -7042,13 +7059,13 @@ void LLVoiceClient::addAutoAcceptRule(const std::string &autoAcceptMask, const s } } -LLVoiceClient::voiceFontEntry::voiceFontEntry(const std::string &id) : +LLVoiceClient::voiceFontEntry::voiceFontEntry(S32 id) : mID(id), mHasExpired(false) { } -LLVoiceClient::voiceFontEntry *LLVoiceClient::addSessionFont(const std::string &id, +LLVoiceClient::voiceFontEntry *LLVoiceClient::addSessionFont(const voice_font_id_t &id, const std::string &name, const std::string &description, const std::string &expirationDate, @@ -7058,7 +7075,7 @@ LLVoiceClient::voiceFontEntry *LLVoiceClient::addSessionFont(const std::string & { voiceFontEntry *font = NULL; - voiceFontMap::iterator iter = mSessionFontMap.find(&id); + voice_font_map_t::iterator iter = mSessionFontMap.find(id); if(iter != mSessionFontMap.end()) { // Found session font already in the map. @@ -7077,11 +7094,39 @@ LLVoiceClient::voiceFontEntry *LLVoiceClient::addSessionFont(const std::string & font->mFontType = fontType; font->mFontStatus = fontStatus; - mSessionFontMap.insert(voiceFontMap::value_type(&(font->mID), font)); + mSessionFontList.insert(voice_font_list_t::value_type(font->mID, &(font->mName))); + mSessionFontMap.insert(voice_font_map_t::value_type(font->mID, font)); } return font; } +bool LLVoiceClient::setVoiceFont(voice_font_id_t id) +{ + if (!mAudioSession || !mAudioSession->mVoiceEnabled || !mSessionFontsReceived) + { + LL_DEBUGS("Voice") << "Session fonts not available" << LL_ENDL; + return false; + } + + if(id == 0 || mSessionFontMap.find(id) != mSessionFontMap.end()) + { + mFontID = id; + } + else + { + LL_DEBUGS("Voice") << "Invalid session font " << id << LL_ENDL; + return false; + } + + sessionSetVoiceFontSendMessage(mAudioSession); + return true; +} + +const LLVoiceClient::voice_font_id_t LLVoiceClient::getVoiceFont() const +{ + return mFontID; +} + void LLVoiceClient::accountListBlockRulesResponse(int statusCode, const std::string &statusString) { // Block list entries were updated via addBlockRule() during parsing. Just flag that we're done. diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 2d8fff5508..05e9dcc896 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -428,8 +428,8 @@ static void updatePosition(void); struct voiceFontEntry { - voiceFontEntry(const std::string &id); - std::string mID; + voiceFontEntry(S32 id); + S32 mID; std::string mName; std::string mDescription; std::string mExpirationDate; @@ -438,9 +438,16 @@ static void updatePosition(void); std::string mFontStatus; }; - typedef std::map voiceFontMap; + typedef S32 voice_font_id_t; + typedef std::map voice_font_list_t; + typedef std::map voice_font_map_t; - voiceFontEntry *addSessionFont(const std::string &id, + bool getVoiceFontsAvailable() const { return mSessionFontsReceived; }; + bool setVoiceFont(voice_font_id_t id); + const voice_font_id_t getVoiceFont() const; + const voice_font_list_t &getVoiceFontList() const { return mSessionFontList; }; + + voiceFontEntry *addSessionFont(const voice_font_id_t &id, const std::string &name, const std::string &description, const std::string &expirationDate, @@ -478,7 +485,7 @@ static void updatePosition(void); void sessionGroupAddSessionSendMessage(sessionState *session, bool startAudio = true, bool startText = false); void sessionMediaConnectSendMessage(sessionState *session); // just joins the audio session void sessionTextConnectSendMessage(sessionState *session); // just joins the text session - void sessionSetVoiceFontSendMessage(sessionState *session, const std::string &fontId); + void sessionSetVoiceFontSendMessage(sessionState *session); void sessionTerminateSendMessage(sessionState *session); void sessionGroupTerminateSendMessage(sessionState *session); void sessionMediaDisconnectSendMessage(sessionState *session); @@ -510,7 +517,7 @@ static void updatePosition(void); deviceList *getCaptureDevices(); deviceList *getRenderDevices(); - + void setNonSpatialChannel( const std::string &uri, const std::string &credentials); @@ -682,7 +689,9 @@ static void updatePosition(void); buddyListMap mBuddyListMap; bool mSessionFontsReceived; - voiceFontMap mSessionFontMap; + S32 mFontID; + voice_font_list_t mSessionFontList; + voice_font_map_t mSessionFontMap; // *TODO: make private deviceList mCaptureDevices; deviceList mRenderDevices; diff --git a/indra/newview/skins/default/xui/en/floater_voice_controls.xml b/indra/newview/skins/default/xui/en/floater_voice_controls.xml index c4411db8c5..100a060557 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml @@ -33,6 +33,9 @@ name="no_one_near"> No one near has voice enabled + + No Voice Effect + - + + + + + + + Date: Fri, 9 Apr 2010 01:29:03 +0100 Subject: Added a method to clear the session font list --- indra/newview/llvoiceclient.cpp | 25 ++++++++++++++++--------- indra/newview/llvoiceclient.h | 15 ++++++++------- 2 files changed, 24 insertions(+), 16 deletions(-) (limited to 'indra') diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 4ea4d9c16e..8fe734030f 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -527,7 +527,7 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr) nameString.clear(); descriptionString.clear(); expirationDateString.clear(); - hasExpired.clear(); + hasExpired = false; fontTypeString.clear(); fontStatusString.clear(); } @@ -7157,13 +7157,21 @@ LLVoiceClient::voiceFontEntry::voiceFontEntry(S32 id) : { } -LLVoiceClient::voiceFontEntry *LLVoiceClient::addSessionFont(const voice_font_id_t &id, - const std::string &name, - const std::string &description, - const std::string &expirationDate, - const bool hasExpired, - const std::string &fontType, - const std::string &fontStatus) +void LLVoiceClient::clearSessionFonts() +{ + // *FIX: Currently set voice font will be invalid + mSessionFontsReceived = false; + mSessionFontList.clear(); + mSessionFontMap.clear(); +} + +void LLVoiceClient::addSessionFont(const voice_font_id_t &id, + const std::string &name, + const std::string &description, + const std::string &expirationDate, + const bool hasExpired, + const std::string &fontType, + const std::string &fontStatus) { voiceFontEntry *font = NULL; @@ -7189,7 +7197,6 @@ LLVoiceClient::voiceFontEntry *LLVoiceClient::addSessionFont(const voice_font_id mSessionFontList.insert(voice_font_list_t::value_type(font->mID, &(font->mName))); mSessionFontMap.insert(voice_font_map_t::value_type(font->mID, font)); } - return font; } bool LLVoiceClient::setVoiceFont(voice_font_id_t id) diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 0df4e4bb3b..9409e19644 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -452,13 +452,14 @@ static void updatePosition(void); const voice_font_id_t getVoiceFont() const; const voice_font_list_t &getVoiceFontList() const { return mSessionFontList; }; - voiceFontEntry *addSessionFont(const voice_font_id_t &id, - const std::string &name, - const std::string &description, - const std::string &expirationDate, - const bool hasExpired, - const std::string &fontType, - const std::string &fontStatus); + void clearSessionFonts(); + void addSessionFont(const voice_font_id_t &id, + const std::string &name, + const std::string &description, + const std::string &expirationDate, + const bool hasExpired, + const std::string &fontType, + const std::string &fontStatus); void accountGetSessionFontsResponse(int statusCode, const std::string &statusString); ///////////////////////////// -- cgit v1.2.3 From e9b613e8d4362412a03b8c141614553f902a24b3 Mon Sep 17 00:00:00 2001 From: Aimee Linden Date: Mon, 19 Apr 2010 15:16:48 +0100 Subject: Identify fonts with UUIDs rather than using the font indexes directly as they are not guaranteed unique across sessions. Replaced all references to "Font" with "Voice Font" where possible to reduce confusion for anyone grepping code in future. --- indra/newview/llcallfloater.cpp | 6 +- indra/newview/llvoicechannel.cpp | 6 +- indra/newview/llvoiceclient.cpp | 253 ++++++++++++++++++++++++++------------- indra/newview/llvoiceclient.h | 97 +++++++++------ 4 files changed, 241 insertions(+), 121 deletions(-) (limited to 'indra') diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index f13e74679d..30f211d46d 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -250,15 +250,15 @@ void LLCallFloater::updateVoiceFont() if (mVoiceFont) { mVoiceFont->removeall(); - mVoiceFont->add(getString("no_voice_font"), 0); + mVoiceFont->add(getString("no_voice_font"), LLUUID::null); - if (LLVoiceClient::getInstance()->getVoiceFontsAvailable()) + if (LLVoiceClient::getInstance()->hasVoiceFonts()) { const LLVoiceClient::voice_font_list_t font_list = LLVoiceClient::getInstance()->getVoiceFontList(); for (LLVoiceClient::voice_font_list_t::const_iterator it = font_list.begin(); it != font_list.end(); ++it) { - mVoiceFont->add(*(it->second), it->first, ADD_BOTTOM); + mVoiceFont->add(*(it->first), *(it->second), ADD_BOTTOM); } mVoiceFont->setEnabled(true); mVoiceFont->setValue(LLVoiceClient::getInstance()->getVoiceFont()); diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp index 7bb1006e93..9ab0bf9552 100644 --- a/indra/newview/llvoicechannel.cpp +++ b/indra/newview/llvoicechannel.cpp @@ -887,9 +887,9 @@ void LLVoiceChannelP2P::setSessionHandle(const std::string& handle, const std::s else { LL_WARNS("Voice") << "incoming SIP URL is not provided. Channel may not work properly." << LL_ENDL; - // In case of incoming AvaLine call generated URI will be differ from original one. - // This is because Avatar-2-Avatar URI is based on avatar UUID but Avaline is not. - // See LLVoiceClient::sessionAddedEvent() -> setUUIDFromStringHash() + // In the case of an incoming AvaLine call, the generated URI will be different from the + // original one. This is because the P2P URI is based on avatar UUID but Avaline is not. + // See LLVoiceClient::sessionAddedEvent() setURI(LLVoiceClient::getInstance()->sipURIFromID(mOtherUserID)); } diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 8fe734030f..00f0c70c17 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -73,15 +73,11 @@ #include "llvoavatarself.h" #include "llvoicechannel.h" +#include "stringize.h" + // for base64 decoding #include "apr_base64.h" -// for SHA1 hash -#include "apr_sha1.h" - -// for MD5 hash -#include "llmd5.h" - #define USE_SESSION_GROUPS 0 static bool sConnectingToAgni = false; @@ -116,14 +112,6 @@ const int MAX_LOGIN_RETRIES = 12; // blocked is VERY rare and it's better to sacrifice response time in this situation for the sake of stability. const int MAX_NORMAL_JOINING_SPATIAL_NUM = 50; -static void setUUIDFromStringHash(LLUUID &uuid, const std::string &str) -{ - LLMD5 md5_uuid; - md5_uuid.update((const unsigned char*)str.data(), str.size()); - md5_uuid.finalize(); - md5_uuid.raw_digest(uuid.mData); -} - static int scale_mic_volume(float volume) { // incoming volume has the range [0.0 ... 2.0], with 1.0 as the default. @@ -258,8 +246,8 @@ protected: std::string descriptionString; std::string expirationDateString; bool hasExpired; - std::string fontTypeString; - std::string fontStatusString; + S32 fontType; + S32 fontStatus; int participantType; bool isLocallyMuted; bool isModeratorMuted; @@ -519,7 +507,7 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr) } else if (!stricmp("SessionFonts", tag)) { - LLVoiceClient::getInstance()->clearSessionFonts(); + LLVoiceClient::getInstance()->deleteAllVoiceFonts(); } else if (!stricmp("SessionFont", tag)) { @@ -528,8 +516,8 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr) descriptionString.clear(); expirationDateString.clear(); hasExpired = false; - fontTypeString.clear(); - fontStatusString.clear(); + fontType = 0; + fontStatus = 0; } } } @@ -660,7 +648,7 @@ void LLVivoxProtocolParser::EndTag(const char *tag) autoAddAsBuddy = string; else if (!stricmp("SessionFont", tag)) { - LLVoiceClient::getInstance()->addSessionFont(id, nameString, descriptionString, expirationDateString, hasExpired, fontTypeString, fontStatusString); + LLVoiceClient::getInstance()->addVoiceFont(id, nameString, descriptionString, expirationDateString, hasExpired, fontType, fontStatus); } else if (!stricmp("ID", tag)) { @@ -680,11 +668,11 @@ void LLVivoxProtocolParser::EndTag(const char *tag) } else if (!stricmp("Type", tag)) { - fontTypeString = string; + fontType = strtol(string.c_str(), NULL, 10); } else if (!stricmp("Status", tag)) { - fontStatusString = string; + fontStatus = strtol(string.c_str(), NULL, 10); } else if (!stricmp("MessageHeader", tag)) messageHeader = string; @@ -887,8 +875,6 @@ void LLVivoxProtocolParser::processResponse(std::string tag) } else if (!stricmp(eventTypeCstr, "SessionUpdatedEvent")) { - // *TODO: Receive the current SessionFontID? - /* c1_m1000xFnPP04IpREWNkuw1cOXlhw==_sg0 @@ -1391,9 +1377,6 @@ LLVoiceClient::LLVoiceClient() : mBlockRulesListReceived(false), mAutoAcceptRulesListReceived(false), - mSessionFontsReceived(false), - mFontID(0), - mCaptureDeviceDirty(false), mRenderDeviceDirty(false), mSpatialCoordsDirty(false), @@ -1874,7 +1857,8 @@ void LLVoiceClient::stateMachine() // Clean up and reset everything. closeSocket(); deleteAllSessions(); - deleteAllBuddies(); + deleteAllBuddies(); + deleteAllVoiceFonts(); mConnectorHandle.clear(); mAccountHandle.clear(); @@ -2640,6 +2624,7 @@ void LLVoiceClient::stateMachine() mAccountHandle.clear(); deleteAllSessions(); deleteAllBuddies(); + deleteAllVoiceFonts(); if(mVoiceEnabled && !mRelogRequested) { @@ -2829,7 +2814,7 @@ void LLVoiceClient::accountGetSessionFontsSendMessage() { std::ostringstream stream; - LL_DEBUGS("Voice") << "requesting session font list" << LL_ENDL; + LL_DEBUGS("Voice") << "Requesting voice font list." << LL_ENDL; stream << "" @@ -2863,7 +2848,10 @@ void LLVoiceClient::sessionGroupCreateSendMessage() void LLVoiceClient::sessionCreateSendMessage(sessionState *session, bool startAudio, bool startText) { LL_DEBUGS("Voice") << "requesting create: " << session->mSIPURI << LL_ENDL; - + + S32 font_index = getVoiceFontIndex(session->mVoiceFontID); + LL_DEBUGS("Voice") << "Requesting voice font: " << session->mVoiceFontID << " (" << font_index << ")" << LL_ENDL; + session->mCreateInProgress = true; if(startAudio) { @@ -2887,11 +2875,11 @@ void LLVoiceClient::sessionCreateSendMessage(sessionState *session, bool startAu << "" << LLURI::escape(session->mHash, allowed_chars) << "" << "SHA1UserName"; } - + stream << "" << (startAudio?"true":"false") << "" << "" << (startText?"true":"false") << "" - << "" << mFontID << "" + << "" << font_index << "" << "" << mChannelName << "" << "\n\n\n"; writeString(stream.str()); @@ -2900,7 +2888,10 @@ void LLVoiceClient::sessionCreateSendMessage(sessionState *session, bool startAu void LLVoiceClient::sessionGroupAddSessionSendMessage(sessionState *session, bool startAudio, bool startText) { LL_DEBUGS("Voice") << "requesting create: " << session->mSIPURI << LL_ENDL; - + + S32 font_index = getVoiceFontIndex(session->mVoiceFontID); + LL_DEBUGS("Voice") << "Requesting voice font: " << session->mVoiceFontID << " (" << font_index << ")" << LL_ENDL; + session->mCreateInProgress = true; if(startAudio) { @@ -2926,6 +2917,7 @@ void LLVoiceClient::sessionGroupAddSessionSendMessage(sessionState *session, boo << "" << mChannelName << "" << "" << (startAudio?"true":"false") << "" << "" << (startText?"true":"false") << "" + << "" << font_index << "" << "" << password << "" << "SHA1UserName" << "\n\n\n" @@ -2938,6 +2930,9 @@ void LLVoiceClient::sessionMediaConnectSendMessage(sessionState *session) { LL_DEBUGS("Voice") << "connecting audio to session handle: " << session->mHandle << LL_ENDL; + S32 font_index = getVoiceFontIndex(session->mVoiceFontID); + LL_DEBUGS("Voice") << "Requesting voice font: " << session->mVoiceFontID << " (" << font_index << ")" << LL_ENDL; + session->mMediaConnectInProgress = true; std::ostringstream stream; @@ -2946,6 +2941,7 @@ void LLVoiceClient::sessionMediaConnectSendMessage(sessionState *session) << "mHandle << "\" action=\"Session.MediaConnect.1\">" << "" << session->mGroupHandle << "" << "" << session->mHandle << "" + << "" << font_index << "" << "Audio" << "\n\n\n"; @@ -2969,15 +2965,15 @@ void LLVoiceClient::sessionTextConnectSendMessage(sessionState *session) void LLVoiceClient::sessionSetVoiceFontSendMessage(sessionState *session) { - llassert(session); - LL_DEBUGS("Voice") << "requesting voice font: " << mFontID << " in session handle: " << session->mHandle << LL_ENDL; + S32 font_index = getVoiceFontIndex(session->mVoiceFontID); + LL_DEBUGS("Voice") << "Requesting voice font: " << session->mVoiceFontID << " (" << font_index << "), session handle: " << session->mHandle << LL_ENDL; std::ostringstream stream; stream << "" << "" << session->mHandle << "" - << "" << mFontID << "" + << "" << font_index << "" << "\n\n\n"; writeString(stream.str()); @@ -4272,7 +4268,7 @@ void LLVoiceClient::sessionAddedEvent( else { LL_INFOS("Voice") << "Could not generate caller id from uri, using hash of uri " << session->mSIPURI << LL_ENDL; - setUUIDFromStringHash(session->mCallerID, session->mSIPURI); + session->mCallerID.generate(session->mSIPURI); session->mSynthesizedCallerID = true; // Can't look up the name in this case -- we have to extract it from the URI. @@ -5252,7 +5248,7 @@ LLVoiceClient::participantState *LLVoiceClient::sessionState::addParticipant(con { // Create a UUID by hashing the URI, but do NOT set mAvatarIDValid. // This tells both code in LLVoiceClient and code in llfloateractivespeakers.cpp that the ID will not be in the name cache. - setUUIDFromStringHash(result->mAvatarID, uri); + result->mAvatarID.generate(uri); } } @@ -6637,7 +6633,8 @@ LLVoiceClient::sessionState::sessionState() : mReconnect(false), mVolumeDirty(false), mMuteDirty(false), - mParticipantsChanged(false) + mParticipantsChanged(false), + mVoiceFontID(0) { } @@ -7151,69 +7148,128 @@ void LLVoiceClient::addAutoAcceptRule(const std::string &autoAcceptMask, const s } } -LLVoiceClient::voiceFontEntry::voiceFontEntry(S32 id) : +LLVoiceClient::voiceFontEntry::voiceFontEntry(LLUUID& id) : mID(id), - mHasExpired(false) + mFontIndex(0), + mHasExpired(false), + mFontType(VOICE_FONT_TYPE_NONE), + mFontStatus(VOICE_FONT_STATUS_NONE) { } -void LLVoiceClient::clearSessionFonts() +LLVoiceClient::voiceFontEntry::~voiceFontEntry() { - // *FIX: Currently set voice font will be invalid - mSessionFontsReceived = false; - mSessionFontList.clear(); - mSessionFontMap.clear(); } -void LLVoiceClient::addSessionFont(const voice_font_id_t &id, - const std::string &name, - const std::string &description, - const std::string &expirationDate, - const bool hasExpired, - const std::string &fontType, - const std::string &fontStatus) +void LLVoiceClient::deleteAllVoiceFonts() { + // All sessions should be removed first as FontIDs will be invalid + llassert(mSessions.empty()); + + LL_DEBUGS("Voice") << "Clearing voice font list." << LL_ENDL; + + mVoiceFontList.clear(); + + voice_font_map_t::iterator iter; + + for (iter = mVoiceFontMap.begin(); iter == mVoiceFontMap.end(); ++iter) + { + delete iter->second; + } + mVoiceFontMap.clear(); +} + +void LLVoiceClient::addVoiceFont(const S32 font_index, + const std::string &name, + const std::string &description, + const std::string &expiration_date, + const bool has_expired, + const S32 font_type, + const S32 font_status) +{ + // Vivox SessionFontIDs are not guaranteed to remain the same between + // sessions or grids so use a UUID for the name. + + // If received name is not a UUID, fudge one by hashing the name and type + LLUUID font_id; + if (LLUUID::validate(name)) + { + font_id = LLUUID(name); + } + else + { + font_id.generate(STRINGIZE(font_type << ":" << name)); + } + voiceFontEntry *font = NULL; - voice_font_map_t::iterator iter = mSessionFontMap.find(id); - if(iter != mSessionFontMap.end()) + // Hopefully won't happen, but behave gracefully if there is a duplicate + // by Replacing the previous one unless this one has expired. + // *TODO: Should maybe check for the later expiry date if neither has + // expired, and favour user fonts over root fonts? But as we shouldn't + // have duplicates anyway, it's probably not worth the effort. + voice_font_map_t::iterator iter = mVoiceFontMap.find(&font_id); + bool duplicate = (iter != mVoiceFontMap.end()); + if (duplicate) { - // Found session font already in the map. - LL_DEBUGS("Voice") << "existing session font " << id << " : " << name << LL_ENDL; - font = iter->second; + LL_DEBUGS("Voice") << "Voice font " << font_index << " duplicates " << iter->second->mFontIndex << "!" << LL_ENDL; + + if (!has_expired) + { + font = iter->second; + } + } + else + { + font = new voiceFontEntry(font_id); } - if(font == NULL) + if (font) { - LL_DEBUGS("Voice") << "adding session font " << id << " : " << name << (hasExpired?" (Expired)":"") << LL_ENDL; - font = new voiceFontEntry(id); - font->mName = name; - font->mDescription = description; - font->mExpirationDate = expirationDate; - font->mHasExpired = hasExpired; - font->mFontType = fontType; - font->mFontStatus = fontStatus; + font->mFontIndex = font_index; + // Use the description for the human readable name if available, as the + // "name" will probably be a UUID. + font->mName = description.empty() ? name : description; + font->mExpirationDate = expiration_date; + font->mHasExpired = has_expired; + font->mFontType = font_type; + font->mFontStatus = font_status; + + LL_DEBUGS("Voice") << "Adding voice font : " << font_id << " (" << font_index << ") : " << name << (has_expired?" (Expired)":"") << LL_ENDL; + + if (font_type < VOICE_FONT_TYPE_NONE || font_type >= VOICE_FONT_TYPE_UNKNOWN) + { + LL_DEBUGS("Voice") << "Unknown voice font type: " << font_type << LL_ENDL; + } + if (font_status < VOICE_FONT_STATUS_NONE || font_status >= VOICE_FONT_STATUS_UNKNOWN) + { + LL_DEBUGS("Voice") << "Unknown voice font status: " << font_status << LL_ENDL; + } - mSessionFontList.insert(voice_font_list_t::value_type(font->mID, &(font->mName))); - mSessionFontMap.insert(voice_font_map_t::value_type(font->mID, font)); + if (!duplicate) + { + mVoiceFontMap.insert(voice_font_map_t::value_type(&(font->mID), font)); + mVoiceFontList.insert(voice_font_list_t::value_type(&(font->mName), &(font->mID))); + } } } -bool LLVoiceClient::setVoiceFont(voice_font_id_t id) +bool LLVoiceClient::setVoiceFont(const LLUUID& id) { - if (!mAudioSession || !mAudioSession->mVoiceEnabled || !mSessionFontsReceived) + if (!mAudioSession || !mAudioSession->mVoiceEnabled || !hasVoiceFonts()) { - LL_DEBUGS("Voice") << "Session fonts not available" << LL_ENDL; + LL_DEBUGS("Voice") << "Voice fonts not available." << LL_ENDL; return false; } - if(id == 0 || mSessionFontMap.find(id) != mSessionFontMap.end()) + if (id.isNull() || (mVoiceFontMap.find(&id) != mVoiceFontMap.end())) { - mFontID = id; + // *TODO: Check for expired fonts + mAudioSession->mVoiceFontID = id; } else { - LL_DEBUGS("Voice") << "Invalid session font " << id << LL_ENDL; + LL_DEBUGS("Voice") << "Invalid voice font " << id << LL_ENDL; return false; } @@ -7221,9 +7277,48 @@ bool LLVoiceClient::setVoiceFont(voice_font_id_t id) return true; } -const LLVoiceClient::voice_font_id_t LLVoiceClient::getVoiceFont() const +const LLUUID LLVoiceClient::getVoiceFont() +{ + if (mAudioSession) + { + return getVoiceFont(mAudioSession->mHandle); + } + else + { + return LLUUID::null; + } +} + +const LLUUID LLVoiceClient::getVoiceFont(const std::string &session_handle) +{ + LLUUID result; + if (hasVoiceFonts()) + { + sessionState *session = findSession(session_handle); + if (session) + { + result = mAudioSession->mVoiceFontID; + } + } + return result; +} + +S32 LLVoiceClient::getVoiceFontIndex(const LLUUID& id) const { - return mFontID; + S32 result = 0; + if (!id.isNull()) + { + voice_font_map_t::const_iterator it = mVoiceFontMap.find(&id); + if (it != mVoiceFontMap.end()) + { + result = it->second->mFontIndex; + } + else + { + LL_DEBUGS("Voice") << "Selected voice font " << id << " is not available." << LL_ENDL; + } + } + return result; } void LLVoiceClient::accountListBlockRulesResponse(int statusCode, const std::string &statusString) @@ -7240,9 +7335,7 @@ void LLVoiceClient::accountListAutoAcceptRulesResponse(int statusCode, const std void LLVoiceClient::accountGetSessionFontsResponse(int statusCode, const std::string &statusString) { - // Session font list entries were updated via addSessionFont() during parsing. Just flag that we're done. - mSessionFontsReceived = true; - + // Voice font list entries were updated via addVoiceFont() during parsing. if(getState() == stateLoggedIn) { setState(stateFontListReceived); diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 9409e19644..f6af389b60 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -358,6 +358,8 @@ static void updatePosition(void); bool mParticipantsChanged; participantMap mParticipantsByURI; participantUUIDMap mParticipantsByUUID; + + LLUUID mVoiceFontID; }; participantState *findParticipantByID(const LLUUID& id); @@ -431,35 +433,24 @@ static void updatePosition(void); void accountListBlockRulesResponse(int statusCode, const std::string &statusString); void accountListAutoAcceptRulesResponse(int statusCode, const std::string &statusString); - struct voiceFontEntry - { - voiceFontEntry(S32 id); - S32 mID; - std::string mName; - std::string mDescription; - std::string mExpirationDate; - bool mHasExpired; - std::string mFontType; - std::string mFontStatus; - }; - - typedef S32 voice_font_id_t; - typedef std::map voice_font_list_t; - typedef std::map voice_font_map_t; - - bool getVoiceFontsAvailable() const { return mSessionFontsReceived; }; - bool setVoiceFont(voice_font_id_t id); - const voice_font_id_t getVoiceFont() const; - const voice_font_list_t &getVoiceFontList() const { return mSessionFontList; }; - - void clearSessionFonts(); - void addSessionFont(const voice_font_id_t &id, - const std::string &name, - const std::string &description, - const std::string &expirationDate, - const bool hasExpired, - const std::string &fontType, - const std::string &fontStatus); + ///////////////////////////// + // Voice Fonts + bool hasVoiceFonts() const { return !mVoiceFontMap.empty(); }; + bool setVoiceFont(const LLUUID& id); + const LLUUID getVoiceFont(); + const LLUUID getVoiceFont(const std::string &session_handle); + + typedef std::multimap voice_font_list_t; + + const voice_font_list_t &getVoiceFontList() const { return mVoiceFontList; }; + + void addVoiceFont(const S32 id, + const std::string &name, + const std::string &description, + const std::string &expiration_date, + const bool has_expired, + const S32 font_type, + const S32 font_status); void accountGetSessionFontsResponse(int statusCode, const std::string &statusString); ///////////////////////////// @@ -698,10 +689,46 @@ static void updatePosition(void); bool mAutoAcceptRulesListReceived; buddyListMap mBuddyListMap; - bool mSessionFontsReceived; - S32 mFontID; - voice_font_list_t mSessionFontList; - voice_font_map_t mSessionFontMap; // *TODO: make private + // Voice Fonts + + S32 getVoiceFontIndex(const LLUUID& id) const; + void deleteAllVoiceFonts(); + + typedef enum e_voice_font_type + { + VOICE_FONT_TYPE_NONE = 0, + VOICE_FONT_TYPE_ROOT = 1, + VOICE_FONT_TYPE_USER = 2, + VOICE_FONT_TYPE_UNKNOWN + } EVoiceFontType; + + typedef enum e_voice_font_status + { + VOICE_FONT_STATUS_NONE = 0, + VOICE_FONT_STATUS_FREE = 1, + VOICE_FONT_STATUS_NOT_FREE = 2, + VOICE_FONT_STATUS_UNKNOWN + } EVoiceFontStatus; + + struct voiceFontEntry + { + voiceFontEntry(LLUUID& id); + ~voiceFontEntry(); + + LLUUID mID; + S32 mFontIndex; + std::string mName; + std::string mExpirationDate; + bool mHasExpired; + S32 mFontType; + S32 mFontStatus; + }; + typedef std::map voice_font_map_t; + + voice_font_map_t mVoiceFontMap; + voice_font_list_t mVoiceFontList; + + // Audio devices deviceList mCaptureDevices; deviceList mRenderDevices; @@ -714,8 +741,8 @@ static void updatePosition(void); // This should be called when the code detects we have changed parcels. // It initiates the call to the server that gets the parcel channel. void parcelChanged(); - - void switchChannel(std::string uri = std::string(), bool spatial = true, bool no_reconnect = false, bool is_p2p = false, std::string hash = ""); + + void switchChannel(std::string uri = std::string(), bool spatial = true, bool no_reconnect = false, bool is_p2p = false, std::string hash = ""); void joinSession(sessionState *session); static std::string nameFromAvatar(LLVOAvatar *avatar); -- cgit v1.2.3 From d6549677fb0a1f1816813db8be6a04ee55e8b8e1 Mon Sep 17 00:00:00 2001 From: Aimee Linden Date: Mon, 19 Apr 2010 15:38:17 +0100 Subject: Removed left over initialization to 0 of mVoiceFontID from when it was an integer rather than a UUID. --- indra/newview/llvoiceclient.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 8b88fd46a3..6205617016 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -6633,8 +6633,7 @@ LLVoiceClient::sessionState::sessionState() : mReconnect(false), mVolumeDirty(false), mMuteDirty(false), - mParticipantsChanged(false), - mVoiceFontID(0) + mParticipantsChanged(false) { } -- cgit v1.2.3 From 7fc33646853e6853f4afb26079afe1512198c24e Mon Sep 17 00:00:00 2001 From: Aimee Linden Date: Tue, 20 Apr 2010 03:23:03 +0100 Subject: Sort out the state machine in LLVoiceClient to wait for voice fonts properly. --- indra/newview/llvoiceclient.cpp | 34 +++++++++++++++++----------------- indra/newview/llvoiceclient.h | 3 ++- 2 files changed, 19 insertions(+), 18 deletions(-) (limited to 'indra') diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 6205617016..b1f0380029 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -1715,7 +1715,8 @@ std::string LLVoiceClient::state2string(LLVoiceClient::state inState) CASE(stateNeedsLogin); CASE(stateLoggingIn); CASE(stateLoggedIn); - CASE(stateFontListReceived); + CASE(stateVoiceFontsWait); + CASE(stateVoiceFontsReceived); CASE(stateCreatingSessionGroup); CASE(stateNoChannel); CASE(stateJoiningSession); @@ -2293,6 +2294,7 @@ void LLVoiceClient::stateMachine() notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LOGGED_IN); // request the set of available voice fonts + setState(stateVoiceFontsWait); accountGetSessionFontsSendMessage(); // request the current set of block rules (we'll need them when updating the friends list) @@ -2326,17 +2328,21 @@ void LLVoiceClient::stateMachine() writeString(stream.str()); } } - - // accountGetSessionFontsResponse() will transition from here to stateFontListReceived. - - //MARK: stateFontListReceived - case stateFontListReceived: // font list received + break; + //MARK: stateVoiceFontsWait + case stateVoiceFontsWait: // Await voice font list + // accountGetSessionFontsResponse() will transition from here to + // stateVoiceFontsReceived, to ensure we have the voice font list + // before attempting to create a session. + break; + + //MARK: stateVoiceFontsReceived + case stateVoiceFontsReceived: // Voice font list received #if USE_SESSION_GROUPS // create the main session group - sessionGroupCreateSendMessage(); - setState(stateCreatingSessionGroup); + sessionGroupCreateSendMessage(); #else // Not using session groups -- skip the stateCreatingSessionGroup state. setState(stateNoChannel); @@ -7162,16 +7168,10 @@ LLVoiceClient::voiceFontEntry::~voiceFontEntry() void LLVoiceClient::deleteAllVoiceFonts() { - // All sessions should be removed first as FontIDs will be invalid - llassert(mSessions.empty()); - - LL_DEBUGS("Voice") << "Clearing voice font list." << LL_ENDL; - mVoiceFontList.clear(); voice_font_map_t::iterator iter; - - for (iter = mVoiceFontMap.begin(); iter == mVoiceFontMap.end(); ++iter) + for (iter = mVoiceFontMap.begin(); iter != mVoiceFontMap.end(); ++iter) { delete iter->second; } @@ -7335,9 +7335,9 @@ void LLVoiceClient::accountListAutoAcceptRulesResponse(int statusCode, const std void LLVoiceClient::accountGetSessionFontsResponse(int statusCode, const std::string &statusString) { // Voice font list entries were updated via addVoiceFont() during parsing. - if(getState() == stateLoggedIn) + if(getState() == stateVoiceFontsWait) { - setState(stateFontListReceived); + setState(stateVoiceFontsReceived); } } diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index f6af389b60..16fcb1d3f6 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -587,7 +587,8 @@ static void updatePosition(void); stateNeedsLogin, // send login request stateLoggingIn, // waiting for account handle stateLoggedIn, // account handle received - stateFontListReceived, // List of available voice fonts received + stateVoiceFontsWait, // Awaiting the list of voice fonts + stateVoiceFontsReceived, // List of voice fonts received stateCreatingSessionGroup, // Creating the main session group stateNoChannel, // stateJoiningSession, // waiting for session handle -- cgit v1.2.3 From cacfa18643092547e7665b36d482ad9c8c5dfc54 Mon Sep 17 00:00:00 2001 From: Aimee Linden Date: Wed, 28 Apr 2010 03:33:15 +0100 Subject: Persist Voice Font selection. Added 'VoiceFontDefault' saved setting. Implemented LLVoiceClientFontsObserver to update the UI when the voice font list is received. Renamed LLVoiceClientParticipantObserver::onChange() to onParticipantsChanged to avoid ambiguity and make the code more readable. Made the Voice Font combo in the VCP auto resize to make best use of the available space when the 'Leave Call button is not visible. --- indra/newview/app_settings/settings.xml | 11 ++++ indra/newview/llcallfloater.cpp | 64 ++++++++++------------ indra/newview/llcallfloater.h | 10 +++- indra/newview/llparticipantlist.cpp | 2 +- indra/newview/llspeakingindicatormanager.cpp | 4 +- indra/newview/llvoicechannel.h | 2 +- indra/newview/llvoiceclient.cpp | 35 +++++++++++- indra/newview/llvoiceclient.h | 17 +++++- .../default/xui/en/floater_voice_controls.xml | 12 ++-- 9 files changed, 106 insertions(+), 51 deletions(-) (limited to 'indra') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 4ca23e14a1..63e8775d04 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10405,6 +10405,17 @@ Value 0 + VoiceFontDefault + + Comment + Selected voice font + Persist + 1 + Type + String + Value + 00000000-0000-0000-0000-000000000000 + AutoDisengageMic Comment diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index f41875f67b..703c7dd435 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -115,7 +115,8 @@ LLCallFloater::LLCallFloater(const LLSD& key) mSpeakerDelayRemover = new LLSpeakersDelayActionsStorage(boost::bind(&LLCallFloater::removeVoiceLeftParticipant, this, _1), voice_left_remove_delay); mFactoryMap["non_avatar_caller"] = LLCallbackMap(create_non_avatar_caller, NULL); - LLVoiceClient::getInstance()->addObserver(this); + LLVoiceClient::instance().addObserver(dynamic_cast(this)); + LLVoiceClient::instance().addObserver(dynamic_cast(this)); LLTransientFloaterMgr::getInstance()->addControlView(this); // force docked state since this floater doesn't save it between recreations @@ -135,7 +136,8 @@ LLCallFloater::~LLCallFloater() if(LLVoiceClient::instanceExists()) { - LLVoiceClient::instance().removeObserver(this); + LLVoiceClient::instance().removeObserver(dynamic_cast(this)); + LLVoiceClient::instance().removeObserver(dynamic_cast(this)); } LLTransientFloaterMgr::getInstance()->removeControlView(this); } @@ -208,11 +210,8 @@ void LLCallFloater::draw() } // virtual -void LLCallFloater::onChange() +void LLCallFloater::onParticipantsChanged() { - // *FIX: Temporarily dumping this here till I decide where it should go - updateVoiceFont(); - if (NULL == mParticipants) return; updateParticipantsVoiceState(); @@ -226,42 +225,23 @@ void LLCallFloater::onChange() } } -////////////////////////////////////////////////////////////////////////// -/// PRIVATE SECTION -////////////////////////////////////////////////////////////////////////// - -void LLCallFloater::leaveCall() -{ - LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel(); - if (voice_channel) - { - gIMMgr->endCall(voice_channel->getSessionID()); - } -} - -/* static */ -void LLCallFloater::commitVoiceFont(LLUICtrl* ctrl, void* userdata) -{ - LLVoiceClient::getInstance()->setVoiceFont(ctrl->getValue()); -} - -void LLCallFloater::updateVoiceFont() +// virtual +void LLCallFloater::onVoiceFontsChanged() { if (mVoiceFont) { mVoiceFont->removeall(); mVoiceFont->add(getString("no_voice_font"), LLUUID::null); - if (LLVoiceClient::getInstance()->hasVoiceFonts()) + if (LLVoiceClient::instance().hasVoiceFonts()) { - const LLVoiceClient::voice_font_list_t font_list = LLVoiceClient::getInstance()->getVoiceFontList(); - + const LLVoiceClient::voice_font_list_t font_list = LLVoiceClient::instance().getVoiceFontList(); for (LLVoiceClient::voice_font_list_t::const_iterator it = font_list.begin(); it != font_list.end(); ++it) { mVoiceFont->add(*(it->first), *(it->second), ADD_BOTTOM); } mVoiceFont->setEnabled(true); - mVoiceFont->setValue(LLVoiceClient::getInstance()->getVoiceFont()); + mVoiceFont->setValue(LLVoiceClient::instance().getVoiceFont()); } else { @@ -270,6 +250,25 @@ void LLCallFloater::updateVoiceFont() } } +////////////////////////////////////////////////////////////////////////// +/// PRIVATE SECTION +////////////////////////////////////////////////////////////////////////// + +void LLCallFloater::leaveCall() +{ + LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel(); + if (voice_channel) + { + gIMMgr->endCall(voice_channel->getSessionID()); + } +} + +/* static */ +void LLCallFloater::commitVoiceFont(LLUICtrl* ctrl, void* userdata) +{ + LLVoiceClient::getInstance()->setVoiceFont(ctrl->getValue()); +} + void LLCallFloater::updateSession() { LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel(); @@ -334,7 +333,7 @@ void LLCallFloater::updateSession() } updateTitle(); - + //hide "Leave Call" button for nearby chat bool is_local_chat = mVoiceType == VC_LOCAL_CHAT; childSetVisible("leave_call_btn_panel", !is_local_chat); @@ -787,9 +786,6 @@ void LLCallFloater::updateState(const LLVoiceChannel::EState& new_state) { reset(new_state); } - - // *FIX: Dumped here till I decide where to put it - updateVoiceFont(); } void LLCallFloater::reset(const LLVoiceChannel::EState& new_state) diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h index 9a13d853c9..160eff312c 100644 --- a/indra/newview/llcallfloater.h +++ b/indra/newview/llcallfloater.h @@ -58,7 +58,9 @@ class LLSpeakersDelayActionsStorage; * When the Resident is engaged in any chat except Nearby Chat, the Voice Control Panel * also provides a 'Leave Call' button to allow the Resident to leave that voice channel. */ -class LLCallFloater : public LLTransientDockableFloater, LLVoiceClientParticipantObserver +class LLCallFloater : public LLTransientDockableFloater, + LLVoiceClientParticipantObserver, + LLVoiceClientFontsObserver { public: @@ -76,7 +78,10 @@ public: * * Refreshes list to display participants not in voice as disabled. */ - /*virtual*/ void onChange(); + /*virtual*/ void onParticipantsChanged(); + + /// Called by LLVoiceClient::notifyVoiceFontObservers when voice font list is changed. + /*virtual*/ void onVoiceFontsChanged(); static void sOnCurrentChannelChanged(const LLUUID& session_id); @@ -103,7 +108,6 @@ private: void leaveCall(); static void commitVoiceFont(LLUICtrl*,void* userdata); - void updateVoiceFont(); /** * Updates mSpeakerManager and list according to current Voice Channel diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index c3748ca81d..d0c882e16e 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -92,7 +92,7 @@ public: mAvalineCallers.insert(avaline_caller_id); } - void onChange() + void onParticipantsChanged() { uuid_set_t participant_uuids; LLVoiceClient::getInstance()->getParticipantsUUIDSet(participant_uuids); diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp index cc06179481..70028dc21b 100644 --- a/indra/newview/llspeakingindicatormanager.cpp +++ b/indra/newview/llspeakingindicatormanager.cpp @@ -107,7 +107,7 @@ private: * So, method does not calculate difference between these list it only switches off already * switched on indicators and switches on indicators of voice channel participants */ - void onChange(); + void onParticipantsChanged(); /** * Changes state of indicators specified by LLUUIDs @@ -205,7 +205,7 @@ void SpeakingIndicatorManager::sOnCurrentChannelChanged(const LLUUID& /*session_ mSwitchedIndicatorsOn.clear(); } -void SpeakingIndicatorManager::onChange() +void SpeakingIndicatorManager::onParticipantsChanged() { LL_DEBUGS("SpeakingIndicator") << "Voice participant list was changed, updating indicators" << LL_ENDL; diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h index 941cccacc3..5236b11853 100644 --- a/indra/newview/llvoicechannel.h +++ b/indra/newview/llvoicechannel.h @@ -112,7 +112,7 @@ protected: void doSetState(const EState& state); void setURI(std::string uri); - // there can be two directions ICOMING and OUTGOING + // there can be two directions INCOMING and OUTGOING EDirection mCallDirection; std::string mURI; diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index b1f0380029..d131285512 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -6641,6 +6641,7 @@ LLVoiceClient::sessionState::sessionState() : mMuteDirty(false), mParticipantsChanged(false) { + mVoiceFontID = LLUUID(gSavedSettings.getString("VoiceFontDefault")); } LLVoiceClient::sessionState::~sessionState() @@ -7263,8 +7264,11 @@ bool LLVoiceClient::setVoiceFont(const LLUUID& id) if (id.isNull() || (mVoiceFontMap.find(&id) != mVoiceFontMap.end())) { - // *TODO: Check for expired fonts + // *TODO: Check for expired fonts? mAudioSession->mVoiceFontID = id; + + // *TODO: Separate voice font defaults for spatial chat and IM? + gSavedSettings.setString("VoiceFontDefault", id.asString()); } else { @@ -7273,6 +7277,7 @@ bool LLVoiceClient::setVoiceFont(const LLUUID& id) } sessionSetVoiceFontSendMessage(mAudioSession); + notifyVoiceFontObservers(); return true; } @@ -7339,6 +7344,7 @@ void LLVoiceClient::accountGetSessionFontsResponse(int statusCode, const std::st { setState(stateVoiceFontsReceived); } + notifyVoiceFontObservers(); } void LLVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer) @@ -7358,12 +7364,35 @@ void LLVoiceClient::notifyParticipantObservers() ) { LLVoiceClientParticipantObserver* observer = *it; - observer->onChange(); - // In case onChange() deleted an entry. + observer->onParticipantsChanged(); + // In case onParticipantsChanged() deleted an entry. it = mParticipantObservers.upper_bound(observer); } } +void LLVoiceClient::addObserver(LLVoiceClientFontsObserver* observer) +{ + mVoiceFontObservers.insert(observer); +} + +void LLVoiceClient::removeObserver(LLVoiceClientFontsObserver* observer) +{ + mVoiceFontObservers.erase(observer); +} + +void LLVoiceClient::notifyVoiceFontObservers() +{ + for (voice_font_observer_set_t::iterator it = mVoiceFontObservers.begin(); + it != mVoiceFontObservers.end(); + ) + { + LLVoiceClientFontsObserver* observer = *it; + observer->onVoiceFontsChanged(); + // In case onVoiceFontsChanged() deleted an entry. + it = mVoiceFontObservers.upper_bound(observer); + } +} + void LLVoiceClient::addObserver(LLVoiceClientStatusObserver* observer) { mStatusObservers.insert(observer); diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 16fcb1d3f6..a1083652aa 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -49,7 +49,14 @@ class LLVoiceClientParticipantObserver { public: virtual ~LLVoiceClientParticipantObserver() { } - virtual void onChange() = 0; + virtual void onParticipantsChanged() = 0; +}; + +class LLVoiceClientFontsObserver +{ +public: + virtual ~LLVoiceClientFontsObserver() { } + virtual void onVoiceFontsChanged() = 0; }; class LLVoiceClientStatusObserver @@ -500,6 +507,9 @@ static void updatePosition(void); void addObserver(LLVoiceClientParticipantObserver* observer); void removeObserver(LLVoiceClientParticipantObserver* observer); + void addObserver(LLVoiceClientFontsObserver* observer); + void removeObserver(LLVoiceClientFontsObserver* observer); + void addObserver(LLVoiceClientStatusObserver* observer); void removeObserver(LLVoiceClientStatusObserver* observer); @@ -832,6 +842,11 @@ static std::string nameFromsipURI(const std::string &uri); void notifyParticipantObservers(); + typedef std::set voice_font_observer_set_t; + voice_font_observer_set_t mVoiceFontObservers; + + void notifyVoiceFontObservers(); + typedef std::set status_observer_set_t; status_observer_set_t mStatusObservers; diff --git a/indra/newview/skins/default/xui/en/floater_voice_controls.xml b/indra/newview/skins/default/xui/en/floater_voice_controls.xml index e7c5770a08..885c8304eb 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml @@ -101,20 +101,20 @@ orientation="horizontal" width="263"> + width="150"> + width="150"> + + + + -- cgit v1.2.3 From 04ef90ceb0829e660d9c89a13ef526b3d30c732c Mon Sep 17 00:00:00 2001 From: Aimee Linden Date: Tue, 18 May 2010 15:55:22 +0100 Subject: EXT-7390 WIP Created SLapp secondlife:///app/voice/effects/refresh to update the voice effect list with new effects. --- indra/newview/llvoiceclient.cpp | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 52a7de61a0..d44b47707e 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -35,6 +35,7 @@ #include "llviewerwindow.h" #include "llvoicevivox.h" #include "llviewernetwork.h" +#include "llcommandhandler.h" #include "llhttpnode.h" #include "llnotificationsutil.h" #include "llsdserialize.h" @@ -46,6 +47,39 @@ const F32 LLVoiceClient::VOLUME_MIN = 0.f; const F32 LLVoiceClient::VOLUME_DEFAULT = 0.5f; const F32 LLVoiceClient::VOLUME_MAX = 1.0f; + +// Support for secondlife:///app/voice SLapps +class LLVoiceHandler : public LLCommandHandler +{ +public: + // requests will be throttled from a non-trusted browser + LLVoiceHandler() : LLCommandHandler("voice", UNTRUSTED_THROTTLE) {} + + bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) + { + if (params[0].asString() == "effects") + { + LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); + // If the voice client doesn't support voice effects, we can't handle effects SLapps + if (!effect_interface) + { + return false; + } + + // Support secondlife:///app/voice/effects/refresh to update the voice effect list with new effects + if (params[1].asString() == "refresh") + { + effect_interface->refreshVoiceEffectLists(false); + return true; + } + } + return false; + } +}; +LLVoiceHandler gVoiceHandler; + + + std::string LLVoiceClientStatusObserver::status2string(LLVoiceClientStatusObserver::EStatusType inStatus) { std::string result = "UNKNOWN"; @@ -77,7 +111,6 @@ std::string LLVoiceClientStatusObserver::status2string(LLVoiceClientStatusObserv - /////////////////////////////////////////////////////////////////////////////////////////////// LLVoiceClient::LLVoiceClient() : -- cgit v1.2.3 From be0662234565f772fc4c89e47400dc9df8277800 Mon Sep 17 00:00:00 2001 From: Aimee Linden Date: Wed, 19 May 2010 16:25:52 +0100 Subject: EXT-7337 WIP Voice font previewing Added LLVoiceEffectInterface::getVoiceEffectProperties Added LLVivoxVoiceClient::getVoiceFontTemplateIndex --- indra/newview/llvoicevivox.cpp | 50 +++++++++++++++++++++++++++++++++++++++++- indra/newview/llvoicevivox.h | 2 ++ 2 files changed, 51 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index ee67879d3d..2df9152a17 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -6378,6 +6378,36 @@ const LLUUID LLVivoxVoiceClient::getVoiceEffect() return mAudioSession ? mAudioSession->mVoiceFontID : LLUUID::null; } +LLSD LLVivoxVoiceClient::getVoiceEffectProperties(const LLUUID& id) +{ + LLSD sd; + + voice_font_map_t::iterator iter = mVoiceFontMap.find(id); + if (iter != mVoiceFontMap.end()) + { + sd["template_only"] = false; + } + else + { + // Voice effect is not in the voice font map, see if there is a template + iter = mVoiceFontTemplateMap.find(id); + if (iter == mVoiceFontTemplateMap.end()) + { + LL_WARNS("Voice") << "Voice effect " << id << "not found." << LL_ENDL; + return sd; + } + sd["template_only"] = true; + } + + voiceFontEntry *font = iter->second; + sd["name"] = font->mName; + sd["expired"] = font->mHasExpired; + sd["expiry_date"] = font->mExpirationDate; + sd["is_new"] = font->mIsNew; + + return sd; +} + LLVivoxVoiceClient::voiceFontEntry::voiceFontEntry(LLUUID& id) : mID(id), mFontIndex(0), @@ -6536,6 +6566,24 @@ S32 LLVivoxVoiceClient::getVoiceFontIndex(const LLUUID& id) const return result; } +S32 LLVivoxVoiceClient::getVoiceFontTemplateIndex(const LLUUID& id) const +{ + S32 result = 0; + if (!id.isNull()) + { + voice_font_map_t::const_iterator it = mVoiceFontTemplateMap.find(id); + if (it != mVoiceFontTemplateMap.end()) + { + result = it->second->mFontIndex; + } + else + { + LL_DEBUGS("Voice") << "Selected voice font template " << id << " is not available." << LL_ENDL; + } + } + return result; +} + void LLVivoxVoiceClient::accountGetSessionFontsSendMessage() { if(!mAccountHandle.empty()) @@ -6753,7 +6801,7 @@ void LLVivoxVoiceClient::captureBufferPlayStartSendMessage(const LLUUID& voice_f LL_DEBUGS("Voice") << "Starting audio buffer playback." << LL_ENDL; - S32 font_index = getVoiceFontIndex(voice_font_id); + S32 font_index = getVoiceFontTemplateIndex(voice_font_id); LL_DEBUGS("Voice") << "With voice font: " << voice_font_id << " (" << font_index << ")" << LL_ENDL; stream diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index 6c302962a3..1047d2e5ed 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -240,6 +240,7 @@ public: //@{ virtual bool setVoiceEffect(const LLUUID& id); virtual const LLUUID getVoiceEffect(); + virtual LLSD getVoiceEffectProperties(const LLUUID& id); virtual void refreshVoiceEffectLists(bool clear_lists); virtual const voice_effect_list_t& getVoiceEffectList() const; @@ -859,6 +860,7 @@ private: void deleteVoiceFontTemplates(); S32 getVoiceFontIndex(const LLUUID& id) const; + S32 getVoiceFontTemplateIndex(const LLUUID& id) const; void accountGetSessionFontsSendMessage(); void accountGetTemplateFontsSendMessage(); -- cgit v1.2.3 From 95ed59a9dec737ffe8d566595e1a74f662fe1e43 Mon Sep 17 00:00:00 2001 From: Aimee Linden Date: Wed, 19 May 2010 16:28:03 +0100 Subject: EXT-7337 WIP Added template voice fonts to the voice font list for previewing --- indra/newview/llfloatervoiceeffect.cpp | 91 ++++++++++++++++++---- indra/newview/llvoiceclient.h | 1 + .../skins/default/xui/en/floater_voice_effect.xml | 89 ++++++++++++++++----- 3 files changed, 150 insertions(+), 31 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloatervoiceeffect.cpp b/indra/newview/llfloatervoiceeffect.cpp index 5a579f5aeb..de12e8d12a 100644 --- a/indra/newview/llfloatervoiceeffect.cpp +++ b/indra/newview/llfloatervoiceeffect.cpp @@ -99,29 +99,94 @@ void LLFloaterVoiceEffect::update() return; } + LL_DEBUGS("Voice")<< "Rebuilding voice effect list."<< LL_ENDL; + + // Preserve selected items and scroll position + S32 scroll_pos = mVoiceEffectList->getScrollPos(); + uuid_vec_t selected_items; + std::vector items = mVoiceEffectList->getAllSelected(); + for(std::vector::const_iterator it = items.begin(); it != items.end(); it++) + { + selected_items.push_back((*it)->getUUID()); + } + mVoiceEffectList->deleteAllItems(); - LLSD element; - element["id"] = LLUUID::null; - element["columns"][1]["column"] = "name"; - element["columns"][1]["value"] = getString("no_voice_effect"); - mVoiceEffectList->addElement(element, ADD_BOTTOM); - - const voice_effect_list_t& effect_list = effect_interface->getVoiceEffectList(); - if (!effect_list.empty()) + { - for (voice_effect_list_t::const_iterator it = effect_list.begin(); it != effect_list.end(); ++it) + // Add the "No Voice Effect" entry + LLSD element; + + element["id"] = LLUUID::null; + element["columns"][0]["column"] = "name"; + element["columns"][0]["value"] = getString("no_voice_effect"); + element["columns"][0]["font"]["name"] = "SANSSERIF"; + element["columns"][0]["font"]["style"] = "BOLD"; + + LLScrollListItem* sl_item = mVoiceEffectList->addElement(element, ADD_BOTTOM); + // *HACK: Copied from llfloatergesture.cpp : ["font"]["style"] does not affect font style :( + if(sl_item) { + ((LLScrollListText*)sl_item->getColumn(0))->setFontStyle(LLFontGL::BOLD); + } + } + + const voice_effect_list_t& template_list = effect_interface->getVoiceEffectTemplateList(); + if (!template_list.empty()) + { + for (voice_effect_list_t::const_iterator it = template_list.begin(); it != template_list.end(); ++it) + { + const LLUUID& effect_id = it->second; + std::string effect_name = it->first; + + LLSD effect_properties = effect_interface->getVoiceEffectProperties(effect_id); + bool is_template_only = effect_properties["template_only"].asBoolean(); + bool is_new = effect_properties["is_new"].asBoolean(); + std::string expiry_date = effect_properties["expiry_date"].asString(); + + std::string font_style = "NORMAL"; + if (!is_template_only) + { + font_style = "BOLD"; + } LLSD element; - element["id"] = it->second; - element["columns"][1]["column"] = "name"; - element["columns"][1]["value"] = it->first; - mVoiceEffectList->addElement(element, ADD_BOTTOM); + element["id"] = effect_id; + + element["columns"][0]["column"] = "name"; + element["columns"][0]["value"] = effect_name; + element["columns"][0]["font"]["name"] = "SANSSERIF"; + element["columns"][0]["font"]["style"] = font_style; + element["columns"][1]["column"] = "new"; + element["columns"][1]["value"] = is_new ? getString("new_voice_effect") : ""; + element["columns"][1]["font"]["name"] = "SANSSERIF"; + element["columns"][1]["font"]["style"] = font_style; + + element["columns"][2]["column"] = "expires"; + element["columns"][2]["value"] = !is_template_only ? expiry_date : ""; + element["columns"][2]["font"]["name"] = "SANSSERIF"; + element["columns"][2]["font"]["style"] = font_style; + + LLScrollListItem* sl_item = mVoiceEffectList->addElement(element, ADD_BOTTOM); + // *HACK: Copied from llfloatergesture.cpp : ["font"]["style"] does not affect font style :( + if(sl_item) + { + LLFontGL::StyleFlags style = is_template_only ? LLFontGL::NORMAL : LLFontGL::BOLD; + ((LLScrollListText*)sl_item->getColumn(0))->setFontStyle(style); + } } } + // Re-select items that were selected before, and restore the scroll position + for(uuid_vec_t::iterator it = selected_items.begin(); it != selected_items.end(); it++) + { + mVoiceEffectList->selectByID(*it); + } + mVoiceEffectList->setScrollPos(scroll_pos); + mVoiceEffectList->setValue(effect_interface->getVoiceEffect()); mVoiceEffectList->setEnabled(true); + // Update button states + // *TODO: Should separate this from rebuilding the effects list, to avoid rebuilding it unnecessarily bool recording = effect_interface->isPreviewRecording(); getChild("record_btn")->setVisible(!recording); getChild("record_stop_btn")->setVisible(recording); diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 8d898378d6..5caf26c492 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -289,6 +289,7 @@ public: //@{ virtual bool setVoiceEffect(const LLUUID& id) = 0; virtual const LLUUID getVoiceEffect() = 0; + virtual LLSD getVoiceEffectProperties(const LLUUID& id) = 0; virtual void refreshVoiceEffectLists(bool clear_lists) = 0; virtual const voice_effect_list_t &getVoiceEffectList() const = 0; diff --git a/indra/newview/skins/default/xui/en/floater_voice_effect.xml b/indra/newview/skins/default/xui/en/floater_voice_effect.xml index 5627eb3aff..8f2f13dffe 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_effect.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_effect.xml @@ -16,6 +16,9 @@ No Voice Effect + + New! + - + - - + + + + - + --> @@ -92,19 +145,19 @@ left_delta="0" name="record_stop_btn" top_delta="0" - width="83"> + width="135"> @@ -116,7 +169,7 @@ left_delta="0" name="play_stop_btn" top_delta="0" - width="83"> + width="135"> -- cgit v1.2.3