From 0f61c00218a07a7d487e33256382c4a10561e0c1 Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> 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 + << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.GetSessionFonts.1\">" + << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" + << "</Request>" + << "\n\n\n"; + + writeString(stream.str()); + } +} + void LLVoiceClient::sessionGroupCreateSendMessage() { if(!mAccountHandle.empty()) @@ -2691,6 +2753,7 @@ void LLVoiceClient::sessionCreateSendMessage(sessionState *session, bool startAu stream << "<ConnectAudio>" << (startAudio?"true":"false") << "</ConnectAudio>" << "<ConnectText>" << (startText?"true":"false") << "</ConnectText>" +// << "<VoiceFontID>0</VoiceFontID>" << "<Name>" << mChannelName << "</Name>" << "</Request>\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 + << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.TextConnect.1\">" + << "<SessionHandle>" << session->mHandle << "</SessionHandle>" + << "<SessionFontID>" << fontId << "</SessionFontID>" + << "</Request>\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<const std::string*, voiceFontEntry*, stringMapComparitor> 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 <aimee@lindenlab.com> 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 <aimee@lindenlab.com> 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 @@ </array> <key>tags</key> <array> + <string>Voice</string> </array> </map> </array> 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<LLUUID>& 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<LLComboBox>("voice_font"); + childSetCommitCallback("voice_font", commitVoiceFont, this); // *FIX: childSetCommitCallback deprecated + mNonAvatarCaller = getChild<LLNonAvatarCaller>("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<LLCallFloater>("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? + /* <Event type="SessionUpdatedEvent"> <SessionGroupHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==_sg0</SessionGroupHandle> @@ -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 << "<ConnectAudio>" << (startAudio?"true":"false") << "</ConnectAudio>" << "<ConnectText>" << (startText?"true":"false") << "</ConnectText>" -// << "<VoiceFontID>0</VoiceFontID>" + << "<VoiceFontID>" << mFontID << "</VoiceFontID>" << "<Name>" << mChannelName << "</Name>" << "</Request>\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 - << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.TextConnect.1\">" + << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.SetVoiceFont.1\">" << "<SessionHandle>" << session->mHandle << "</SessionHandle>" - << "<SessionFontID>" << fontId << "</SessionFontID>" + << "<SessionFontID>" << mFontID << "</SessionFontID>" << "</Request>\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<const std::string*, voiceFontEntry*, stringMapComparitor> voiceFontMap; + typedef S32 voice_font_id_t; + typedef std::map<voice_font_id_t, std::string*> voice_font_list_t; + typedef std::map<voice_font_id_t, voiceFontEntry*> 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 </string> + <floater.string name="no_voice_font"> + No Voice Effect + </floater.string> <layout_stack clip="false" follows="all" @@ -84,7 +87,39 @@ visible="true" width="20" /> </layout_panel> - <layout_panel + <layout_stack + clip="false" + auto_resize="false" + follows="left|right" + height="23" + layout="topleft" + left="10" + mouse_opaque="false" + name="voice_font_and_leave_call_stack" + orientation="horizontal" + width="263"> + <layout_panel + auto_resize="false" + user_resize="false" + follows="top|left" + height="26" + visible="true" + layout="topleft" + name="voice_font_panel" + width="120"> + <combo_box + follows="left|top" + height="23" + name="voice_font" + top_pad="0" + width="120"> + <combo_box.item + label="No Voice Effect" + name="no_voice_font" + value="0" /> + </combo_box> + </layout_panel> + <layout_panel auto_resize="false" user_resize="false" follows="top|left" @@ -101,6 +136,7 @@ name="leave_call_btn" width="100" /> </layout_panel> + </layout_stack> <layout_panel follows="all" layout="topleft" -- cgit v1.2.3 From 5a8770c9e37ae3ebe6fca7f8a631be4179763aed Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> 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 <aimee@lindenlab.com> 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? - /* <Event type="SessionUpdatedEvent"> <SessionGroupHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==_sg0</SessionGroupHandle> @@ -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 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.GetSessionFonts.1\">" @@ -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 << "<Password>" << LLURI::escape(session->mHash, allowed_chars) << "</Password>" << "<PasswordHashAlgorithm>SHA1UserName</PasswordHashAlgorithm>"; } - + stream << "<ConnectAudio>" << (startAudio?"true":"false") << "</ConnectAudio>" << "<ConnectText>" << (startText?"true":"false") << "</ConnectText>" - << "<VoiceFontID>" << mFontID << "</VoiceFontID>" + << "<VoiceFontID>" << font_index << "</VoiceFontID>" << "<Name>" << mChannelName << "</Name>" << "</Request>\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 << "<Name>" << mChannelName << "</Name>" << "<ConnectAudio>" << (startAudio?"true":"false") << "</ConnectAudio>" << "<ConnectText>" << (startText?"true":"false") << "</ConnectText>" + << "<VoiceFontID>" << font_index << "</VoiceFontID>" << "<Password>" << password << "</Password>" << "<PasswordHashAlgorithm>SHA1UserName</PasswordHashAlgorithm>" << "</Request>\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) << "<Request requestId=\"" << session->mHandle << "\" action=\"Session.MediaConnect.1\">" << "<SessionGroupHandle>" << session->mGroupHandle << "</SessionGroupHandle>" << "<SessionHandle>" << session->mHandle << "</SessionHandle>" + << "<VoiceFontID>" << font_index << "</VoiceFontID>" << "<Media>Audio</Media>" << "</Request>\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 << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.SetVoiceFont.1\">" << "<SessionHandle>" << session->mHandle << "</SessionHandle>" - << "<SessionFontID>" << mFontID << "</SessionFontID>" + << "<SessionFontID>" << font_index << "</SessionFontID>" << "</Request>\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_id_t, std::string*> voice_font_list_t; - typedef std::map<voice_font_id_t, voiceFontEntry*> 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<const std::string*, const LLUUID*, stringMapComparitor> 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<const LLUUID*, voiceFontEntry*, uuidMapComparitor> 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 <aimee@lindenlab.com> 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 <aimee@lindenlab.com> 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 <aimee@lindenlab.com> 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 @@ <key>Value</key> <integer>0</integer> </map> + <key>VoiceFontDefault</key> + <map> + <key>Comment</key> + <string>Selected voice font</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>00000000-0000-0000-0000-000000000000</string> + </map> <key>AutoDisengageMic</key> <map> <key>Comment</key> 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<LLVoiceClientParticipantObserver*>(this)); + LLVoiceClient::instance().addObserver(dynamic_cast<LLVoiceClientFontsObserver*>(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<LLVoiceClientParticipantObserver*>(this)); + LLVoiceClient::instance().removeObserver(dynamic_cast<LLVoiceClientFontsObserver*>(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<LLVoiceClientFontsObserver*> voice_font_observer_set_t; + voice_font_observer_set_t mVoiceFontObservers; + + void notifyVoiceFontObservers(); + typedef std::set<LLVoiceClientStatusObserver*> 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"> <layout_panel - auto_resize="false" + auto_resize="true" user_resize="false" follows="top|left" height="26" visible="true" layout="topleft" name="voice_font_panel" - width="120"> + width="150"> <combo_box - follows="left|top" + follows="left|top|right" height="23" name="voice_font" top_pad="0" - width="120"> + width="150"> <combo_box.item label="No Voice Effect" name="no_voice_font" @@ -124,14 +124,14 @@ <layout_panel auto_resize="false" user_resize="false" - follows="top|left" + follows="top|right" height="26" visible="true" layout="topleft" name="leave_call_btn_panel" width="100"> <button - follows="right|top" + follows="right|top" height="23" top_pad="0" label="Leave Call" -- cgit v1.2.3 From 46897efc3efade25feaaa1dc67bc131c35202d12 Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Thu, 29 Apr 2010 02:37:07 +0100 Subject: Make a proper XUI commit_callback for the Voice Font combo --- indra/newview/llcallfloater.cpp | 50 +++++++++++++--------- indra/newview/llcallfloater.h | 3 +- indra/newview/llvoiceclient.cpp | 49 +++++++++------------ indra/newview/llvoiceclient.h | 1 + .../default/xui/en/floater_voice_controls.xml | 9 ++-- 5 files changed, 58 insertions(+), 54 deletions(-) (limited to 'indra') diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index 703c7dd435..37e551890a 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -115,8 +115,10 @@ 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::instance().addObserver(dynamic_cast<LLVoiceClientParticipantObserver*>(this)); LLVoiceClient::instance().addObserver(dynamic_cast<LLVoiceClientFontsObserver*>(this)); + mCommitCallbackRegistrar.add("Voice.CommitVoiceFont", boost::bind(&LLCallFloater::onCommitVoiceFont, this)); LLTransientFloaterMgr::getInstance()->addControlView(this); // force docked state since this floater doesn't save it between recreations @@ -152,8 +154,6 @@ BOOL LLCallFloater::postBuild() childSetAction("leave_call_btn", boost::bind(&LLCallFloater::leaveCall, this)); mVoiceFont = getChild<LLComboBox>("voice_font"); - childSetCommitCallback("voice_font", commitVoiceFont, this); // *FIX: childSetCommitCallback deprecated - mNonAvatarCaller = getChild<LLNonAvatarCaller>("non_avatar_caller"); mNonAvatarCaller->setVisible(FALSE); @@ -227,6 +227,32 @@ void LLCallFloater::onParticipantsChanged() // virtual void LLCallFloater::onVoiceFontsChanged() +{ + updateVoiceFont(); +} + +////////////////////////////////////////////////////////////////////////// +/// PRIVATE SECTION +////////////////////////////////////////////////////////////////////////// + +void LLCallFloater::leaveCall() +{ + LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel(); + if (voice_channel) + { + gIMMgr->endCall(voice_channel->getSessionID()); + } +} + +void LLCallFloater::onCommitVoiceFont() +{ + if (LLVoiceClient::instance().hasVoiceFonts()) + { + LLVoiceClient::getInstance()->setVoiceFont(mVoiceFont->getValue()); + } +} + +void LLCallFloater::updateVoiceFont() { if (mVoiceFont) { @@ -250,25 +276,6 @@ void LLCallFloater::onVoiceFontsChanged() } } -////////////////////////////////////////////////////////////////////////// -/// 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(); @@ -333,6 +340,7 @@ void LLCallFloater::updateSession() } updateTitle(); + updateVoiceFont(); //hide "Leave Call" button for nearby chat bool is_local_chat = mVoiceType == VC_LOCAL_CHAT; diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h index 160eff312c..90b23eb4c4 100644 --- a/indra/newview/llcallfloater.h +++ b/indra/newview/llcallfloater.h @@ -107,7 +107,8 @@ private: void leaveCall(); - static void commitVoiceFont(LLUICtrl*,void* userdata); + void onCommitVoiceFont(); + void updateVoiceFont(); /** * Updates mSpeakerManager and list according to current Voice Channel diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index d131285512..657a130c27 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -7256,55 +7256,46 @@ void LLVoiceClient::addVoiceFont(const S32 font_index, bool LLVoiceClient::setVoiceFont(const LLUUID& id) { - if (!mAudioSession || !mAudioSession->mVoiceEnabled || !hasVoiceFonts()) + return mAudioSession ? setVoiceFont(mAudioSession->mHandle, id) : false; +} + +bool LLVoiceClient::setVoiceFont(const std::string &session_handle, const LLUUID& id) +{ + sessionState *session = findSession(session_handle); + + if (!session || !session->mVoiceEnabled || !hasVoiceFonts()) { LL_DEBUGS("Voice") << "Voice fonts not available." << LL_ENDL; return false; } - if (id.isNull() || (mVoiceFontMap.find(&id) != mVoiceFontMap.end())) - { - // *TODO: Check for expired fonts? - mAudioSession->mVoiceFontID = id; - - // *TODO: Separate voice font defaults for spatial chat and IM? - gSavedSettings.setString("VoiceFontDefault", id.asString()); - } - else + if (!id.isNull() && (mVoiceFontMap.find(&id) == mVoiceFontMap.end())) { LL_DEBUGS("Voice") << "Invalid voice font " << id << LL_ENDL; return false; } - sessionSetVoiceFontSendMessage(mAudioSession); + // *TODO: Check for expired fonts? + mAudioSession->mVoiceFontID = id; + + // *TODO: Separate voice font defaults for spatial chat and IM? + gSavedSettings.setString("VoiceFontDefault", id.asString()); + + sessionSetVoiceFontSendMessage(session); notifyVoiceFontObservers(); + return true; } const LLUUID LLVoiceClient::getVoiceFont() { - if (mAudioSession) - { - return getVoiceFont(mAudioSession->mHandle); - } - else - { - return LLUUID::null; - } + return mAudioSession ? getVoiceFont(mAudioSession->mHandle) : 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; + sessionState *session = findSession(session_handle); + return session ? session->mVoiceFontID : LLUUID::null; } S32 LLVoiceClient::getVoiceFontIndex(const LLUUID& id) const diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index a1083652aa..a997f9d500 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -444,6 +444,7 @@ static void updatePosition(void); // Voice Fonts bool hasVoiceFonts() const { return !mVoiceFontMap.empty(); }; bool setVoiceFont(const LLUUID& id); + bool setVoiceFont(const std::string &session_handle, const LLUUID& id); const LLUUID getVoiceFont(); const LLUUID getVoiceFont(const std::string &session_handle); 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 885c8304eb..44840a82d0 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml @@ -110,15 +110,18 @@ name="voice_font_panel" width="150"> <combo_box + enabled="false" follows="left|top|right" height="23" name="voice_font" top_pad="0" width="150"> <combo_box.item - label="No Voice Effect" - name="no_voice_font" - value="0" /> + label="No Voice Effect" + name="no_voice_font" + value="0" /> + <combo_box.commit_callback + function="Voice.CommitVoiceFont" /> </combo_box> </layout_panel> <layout_panel -- cgit v1.2.3 From 93a93dfc92d5339a70f6174ae74b96fc4cb2813f Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Thu, 29 Apr 2010 13:42:34 +0100 Subject: Added VoiceFontUI setting for SLE --- indra/newview/app_settings/settings.xml | 11 +++++++++++ indra/newview/skins/default/xui/en/floater_voice_controls.xml | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 45de05ae82..3a80579c7f 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10427,6 +10427,17 @@ <key>Value</key> <string>00000000-0000-0000-0000-000000000000</string> </map> + <key>VoiceFontUI</key> + <map> + <key>Comment</key> + <string>Whether or not to show the Voice Fonts UI</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>AutoDisengageMic</key> <map> <key>Comment</key> 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 44840a82d0..ce81a39fe0 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml @@ -105,7 +105,7 @@ user_resize="false" follows="top|left" height="26" - visible="true" + visiblity_control="VoiceFontUI" layout="topleft" name="voice_font_panel" width="150"> -- cgit v1.2.3 From 29c2e7ebeca288b051d4851d148b1f82a06d24ef Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Thu, 29 Apr 2010 13:47:50 +0100 Subject: Clip the layout_stack so that the "Leave Call" button isn't seen flying in and out of the floater! --- indra/newview/skins/default/xui/en/floater_voice_controls.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra') 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 ce81a39fe0..370bc05c28 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml @@ -90,9 +90,9 @@ width="20" /> </layout_panel> <layout_stack - clip="false" + clip="true" auto_resize="false" - follows="left|right" + follows="left|top|right" height="23" layout="topleft" left="10" -- cgit v1.2.3 From 38f45a359544ff855c624473fe1305ec6933b8c5 Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Thu, 29 Apr 2010 18:38:08 +0100 Subject: Make the current voice font a per-account saved setting. --- indra/newview/app_settings/settings.xml | 11 ----------- indra/newview/app_settings/settings_per_account.xml | 11 +++++++++++ indra/newview/llvoiceclient.cpp | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'indra') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 3a80579c7f..1cb4b15147 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10416,17 +10416,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>VoiceFontDefault</key> - <map> - <key>Comment</key> - <string>Selected voice font</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>String</string> - <key>Value</key> - <string>00000000-0000-0000-0000-000000000000</string> - </map> <key>VoiceFontUI</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index 3ce32a05b0..1855bb0c0c 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -99,6 +99,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>VoiceFontDefault</key> + <map> + <key>Comment</key> + <string>Selected voice font</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>00000000-0000-0000-0000-000000000000</string> + </map> <!-- Settings below are for back compatibility only. They are not used in current viewer anymore. But they can't be removed to avoid diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 657a130c27..497f1db44d 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -6641,7 +6641,7 @@ LLVoiceClient::sessionState::sessionState() : mMuteDirty(false), mParticipantsChanged(false) { - mVoiceFontID = LLUUID(gSavedSettings.getString("VoiceFontDefault")); + mVoiceFontID = LLUUID(gSavedPerAccountSettings.getString("VoiceFontDefault")); } LLVoiceClient::sessionState::~sessionState() @@ -7279,7 +7279,7 @@ bool LLVoiceClient::setVoiceFont(const std::string &session_handle, const LLUUID mAudioSession->mVoiceFontID = id; // *TODO: Separate voice font defaults for spatial chat and IM? - gSavedSettings.setString("VoiceFontDefault", id.asString()); + gSavedPerAccountSettings.setString("VoiceFontDefault", id.asString()); sessionSetVoiceFontSendMessage(session); notifyVoiceFontObservers(); -- cgit v1.2.3 From 7a6474129c6015e102b30570fa474ba48e4c85e0 Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Fri, 30 Apr 2010 19:38:52 +0100 Subject: Move the Voice Font control from LLCallFloater to its own panel so that it can be reused. --- indra/newview/CMakeLists.txt | 2 + indra/newview/llcallfloater.cpp | 57 ++----------------- indra/newview/llcallfloater.h | 12 +--- indra/newview/llvoiceclient.cpp | 7 ++- .../default/xui/en/floater_voice_controls.xml | 66 +++++++--------------- 5 files changed, 36 insertions(+), 108 deletions(-) (limited to 'indra') diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 835a9aacd5..688886de3a 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -350,6 +350,7 @@ set(viewer_SOURCE_FILES llpanelprofileview.cpp llpanelteleporthistory.cpp llpaneltiptoast.cpp + llpanelvoicefont.cpp llpanelvolume.cpp llpanelvolumepulldown.cpp llparcelselection.cpp @@ -857,6 +858,7 @@ set(viewer_HEADER_FILES llpanelprofileview.h llpanelteleporthistory.h llpaneltiptoast.h + llpanelvoicefont.h llpanelvolume.h llpanelvolumepulldown.h llparcelselection.h diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp index 37e551890a..1c03fbde41 100644 --- a/indra/newview/llcallfloater.cpp +++ b/indra/newview/llcallfloater.cpp @@ -52,7 +52,7 @@ #include "lltransientfloatermgr.h" #include "llviewerwindow.h" #include "llvoicechannel.h" -#include "llvoiceclient.h" // for Voice font list types +#include "llviewercontrol.h" #include "llviewerparcelmgr.h" static void get_voice_participants_uuids(uuid_vec_t& speakers_uuids); @@ -106,7 +106,6 @@ LLCallFloater::LLCallFloater(const LLSD& key) , mNonAvatarCaller(NULL) , mVoiceType(VC_LOCAL_CHAT) , mAgentPanel(NULL) -, mVoiceFont(NULL) , mSpeakingIndicator(NULL) , mIsModeratorMutedVoice(false) , mInitParticipantsVoiceState(false) @@ -115,10 +114,7 @@ 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::instance().addObserver(dynamic_cast<LLVoiceClientParticipantObserver*>(this)); - LLVoiceClient::instance().addObserver(dynamic_cast<LLVoiceClientFontsObserver*>(this)); - mCommitCallbackRegistrar.add("Voice.CommitVoiceFont", boost::bind(&LLCallFloater::onCommitVoiceFont, this)); + LLVoiceClient::instance().addObserver(this); LLTransientFloaterMgr::getInstance()->addControlView(this); // force docked state since this floater doesn't save it between recreations @@ -138,8 +134,7 @@ LLCallFloater::~LLCallFloater() if(LLVoiceClient::instanceExists()) { - LLVoiceClient::instance().removeObserver(dynamic_cast<LLVoiceClientParticipantObserver*>(this)); - LLVoiceClient::instance().removeObserver(dynamic_cast<LLVoiceClientFontsObserver*>(this)); + LLVoiceClient::instance().removeObserver(this); } LLTransientFloaterMgr::getInstance()->removeControlView(this); } @@ -153,7 +148,6 @@ BOOL LLCallFloater::postBuild() childSetAction("leave_call_btn", boost::bind(&LLCallFloater::leaveCall, this)); - mVoiceFont = getChild<LLComboBox>("voice_font"); mNonAvatarCaller = getChild<LLNonAvatarCaller>("non_avatar_caller"); mNonAvatarCaller->setVisible(FALSE); @@ -225,12 +219,6 @@ void LLCallFloater::onParticipantsChanged() } } -// virtual -void LLCallFloater::onVoiceFontsChanged() -{ - updateVoiceFont(); -} - ////////////////////////////////////////////////////////////////////////// /// PRIVATE SECTION ////////////////////////////////////////////////////////////////////////// @@ -244,38 +232,6 @@ void LLCallFloater::leaveCall() } } -void LLCallFloater::onCommitVoiceFont() -{ - if (LLVoiceClient::instance().hasVoiceFonts()) - { - LLVoiceClient::getInstance()->setVoiceFont(mVoiceFont->getValue()); - } -} - -void LLCallFloater::updateVoiceFont() -{ - if (mVoiceFont) - { - mVoiceFont->removeall(); - mVoiceFont->add(getString("no_voice_font"), LLUUID::null); - - if (LLVoiceClient::instance().hasVoiceFonts()) - { - 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::instance().getVoiceFont()); - } - else - { - mVoiceFont->setEnabled(false); - } - } -} - void LLCallFloater::updateSession() { LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel(); @@ -333,23 +289,22 @@ void LLCallFloater::updateSession() if (NULL == mSpeakerManager) { - // by default let show nearby chat participants + // By default show nearby chat participants mSpeakerManager = LLLocalSpeakerMgr::getInstance(); lldebugs << "Set DEFAULT speaker manager" << llendl; mVoiceType = VC_LOCAL_CHAT; } updateTitle(); - updateVoiceFont(); - //hide "Leave Call" button for nearby chat + // Hide "Leave Call" button for nearby chat bool is_local_chat = mVoiceType == VC_LOCAL_CHAT; childSetVisible("leave_call_btn_panel", !is_local_chat); refreshParticipantList(); updateAgentModeratorState(); - //show floater for voice calls & only in CONNECTED to voice channel state + // Show floater for voice calls & only in CONNECTED to voice channel state if (!is_local_chat && voice_channel && LLVoiceChannel::STATE_CONNECTED == voice_channel->getState()) diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h index 90b23eb4c4..e4341175e2 100644 --- a/indra/newview/llcallfloater.h +++ b/indra/newview/llcallfloater.h @@ -40,7 +40,6 @@ class LLAvatarList; class LLAvatarListItem; -class LLComboBox; class LLNonAvatarCaller; class LLOutputMonitorCtrl; class LLParticipantList; @@ -58,9 +57,7 @@ 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, - LLVoiceClientFontsObserver +class LLCallFloater : public LLTransientDockableFloater, LLVoiceClientParticipantObserver { public: @@ -80,9 +77,6 @@ public: */ /*virtual*/ void onParticipantsChanged(); - /// Called by LLVoiceClient::notifyVoiceFontObservers when voice font list is changed. - /*virtual*/ void onVoiceFontsChanged(); - static void sOnCurrentChannelChanged(const LLUUID& session_id); private: @@ -107,9 +101,6 @@ private: void leaveCall(); - void onCommitVoiceFont(); - void updateVoiceFont(); - /** * Updates mSpeakerManager and list according to current Voice Channel * @@ -239,7 +230,6 @@ private: LLNonAvatarCaller* mNonAvatarCaller; EVoiceControls mVoiceType; LLPanel* mAgentPanel; - LLComboBox* mVoiceFont; LLOutputMonitorCtrl* mSpeakingIndicator; bool mIsModeratorMutedVoice; diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 497f1db44d..007d95043d 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -7262,8 +7262,13 @@ bool LLVoiceClient::setVoiceFont(const LLUUID& id) bool LLVoiceClient::setVoiceFont(const std::string &session_handle, const LLUUID& id) { sessionState *session = findSession(session_handle); + if (!session) + { + LL_DEBUGS("Voice") << "Invalid Session." << LL_ENDL; + return false; + } - if (!session || !session->mVoiceEnabled || !hasVoiceFonts()) + if (!hasVoiceFonts()) { LL_DEBUGS("Voice") << "Voice fonts not available." << LL_ENDL; return false; 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 370bc05c28..83380577ca 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml @@ -3,7 +3,7 @@ can_resize="true" can_minimize="true" can_close="false" - height="202" + height="205" layout="topleft" min_height="124" min_width="190" @@ -35,9 +35,6 @@ name="no_one_near"> No one near has voice enabled </string> - <floater.string name="no_voice_font"> - No Voice Effect - </floater.string> <layout_stack clip="false" follows="all" @@ -53,7 +50,7 @@ user_resize="false" auto_resize="false" layout="topleft" - height="26" + height="20" name="my_panel"> <avatar_icon enabled="false" @@ -93,55 +90,34 @@ clip="true" auto_resize="false" follows="left|top|right" - height="23" + height="26" layout="topleft" - left="10" mouse_opaque="false" name="voice_font_and_leave_call_stack" orientation="horizontal" - width="263"> + width="262"> + <panel + class="panel_voice_font" + name="panel_voice_font" + visiblity_control="VoiceFontUI" + filename="panel_voice_font.xml" /> <layout_panel - auto_resize="true" + auto_resize="false" user_resize="false" - follows="top|left" - height="26" - visiblity_control="VoiceFontUI" + follows="top|right" + height="23" + visible="true" layout="topleft" - name="voice_font_panel" - width="150"> - <combo_box - enabled="false" - follows="left|top|right" + name="leave_call_btn_panel" + width="100"> + <button + follows="right|top" height="23" - name="voice_font" - top_pad="0" - width="150"> - <combo_box.item - label="No Voice Effect" - name="no_voice_font" - value="0" /> - <combo_box.commit_callback - function="Voice.CommitVoiceFont" /> - </combo_box> + label="Leave Call" + name="leave_call_btn" + width="100" /> </layout_panel> - <layout_panel - auto_resize="false" - user_resize="false" - follows="top|right" - height="26" - visible="true" - layout="topleft" - name="leave_call_btn_panel" - width="100"> - <button - follows="right|top" - height="23" - top_pad="0" - label="Leave Call" - name="leave_call_btn" - width="100" /> - </layout_panel> - </layout_stack> + </layout_stack> <layout_panel follows="all" layout="topleft" -- cgit v1.2.3 From ba921a37fe5c3a7d8f5542fd3f5edf0d91ee12c7 Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Wed, 12 May 2010 01:54:46 +0100 Subject: EXT-7138 WIP Enumerate template voice fonts. Also simplified LLPanelVoiceFont some. --- indra/newview/llvoiceclient.cpp | 125 +++++++++++++++++++++++++++++----------- indra/newview/llvoiceclient.h | 20 ++++--- 2 files changed, 103 insertions(+), 42 deletions(-) (limited to 'indra') diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 3c1dafc886..e140c6f2ee 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -507,7 +507,7 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr) } else if (!stricmp("SessionFonts", tag)) { - LLVoiceClient::getInstance()->deleteAllVoiceFonts(); + LLVoiceClient::getInstance()->deleteVoiceFonts(); } else if (!stricmp("SessionFont", tag)) { @@ -519,6 +519,20 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr) fontType = 0; fontStatus = 0; } + else if (!stricmp("TemplateFonts", tag)) + { + LLVoiceClient::getInstance()->deleteVoiceFontTemplates(); + } + else if (!stricmp("TemplateFont", tag)) + { + id = 0; + nameString.clear(); + descriptionString.clear(); + expirationDateString.clear(); + hasExpired = false; + fontType = 0; + fontStatus = 0; + } } } responseDepth++; @@ -648,7 +662,11 @@ void LLVivoxProtocolParser::EndTag(const char *tag) autoAddAsBuddy = string; else if (!stricmp("SessionFont", tag)) { - LLVoiceClient::getInstance()->addVoiceFont(id, nameString, descriptionString, expirationDateString, hasExpired, fontType, fontStatus); + LLVoiceClient::getInstance()->addVoiceFont(id, nameString, descriptionString, expirationDateString, hasExpired, fontType, fontStatus, false); + } + else if (!stricmp("TemplateFont", tag)) + { + LLVoiceClient::getInstance()->addVoiceFont(id, nameString, descriptionString, expirationDateString, hasExpired, fontType, fontStatus, true); } else if (!stricmp("ID", tag)) { @@ -948,6 +966,10 @@ void LLVivoxProtocolParser::processResponse(std::string tag) { LLVoiceClient::getInstance()->accountGetSessionFontsResponse(statusCode, statusString); } + else if (!stricmp(actionCstr, "Account.GetTemplateFonts.1")) + { + LLVoiceClient::getInstance()->accountGetTemplateFontsResponse(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. @@ -1859,7 +1881,8 @@ void LLVoiceClient::stateMachine() closeSocket(); deleteAllSessions(); deleteAllBuddies(); - deleteAllVoiceFonts(); + deleteVoiceFonts(); + deleteVoiceFontTemplates(); mConnectorHandle.clear(); mAccountHandle.clear(); @@ -2296,6 +2319,7 @@ void LLVoiceClient::stateMachine() // request the set of available voice fonts setState(stateVoiceFontsWait); accountGetSessionFontsSendMessage(); + accountGetTemplateFontsSendMessage(); // *TODO: Maybe better to do this when opening preview rather than on login // request the current set of block rules (we'll need them when updating the friends list) accountListBlockRulesSendMessage(); @@ -2399,6 +2423,7 @@ void LLVoiceClient::stateMachine() sessionState *oldSession = mAudioSession; mAudioSession = mNextAudioSession; + mAudioSessionChanged = true; if(!mAudioSession->mReconnect) { mNextAudioSession = NULL; @@ -2630,7 +2655,8 @@ void LLVoiceClient::stateMachine() mAccountHandle.clear(); deleteAllSessions(); deleteAllBuddies(); - deleteAllVoiceFonts(); + deleteVoiceFonts(); + deleteVoiceFontTemplates(); if(mVoiceEnabled && !mRelogRequested) { @@ -2711,15 +2737,15 @@ void LLVoiceClient::stateMachine() } - if(mAudioSession && mAudioSession->mParticipantsChanged) + if (mAudioSessionChanged) { - mAudioSession->mParticipantsChanged = false; - mAudioSessionChanged = true; + mAudioSessionChanged = false; + notifyParticipantObservers(); + notifyVoiceFontObservers(); } - - if(mAudioSessionChanged) + else if (mAudioSession && mAudioSession->mParticipantsChanged) { - mAudioSessionChanged = false; + mAudioSession->mParticipantsChanged = false; notifyParticipantObservers(); } } @@ -2832,6 +2858,24 @@ void LLVoiceClient::accountGetSessionFontsSendMessage() } } +void LLVoiceClient::accountGetTemplateFontsSendMessage() +{ + if(!mAccountHandle.empty()) + { + std::ostringstream stream; + + LL_DEBUGS("Voice") << "Requesting voice font template list." << LL_ENDL; + + stream + << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.GetTemplateFonts.1\">" + << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" + << "</Request>" + << "\n\n\n"; + + writeString(stream.str()); + } +} + void LLVoiceClient::sessionGroupCreateSendMessage() { if(!mAccountHandle.empty()) @@ -6640,7 +6684,6 @@ LLVoiceClient::sessionState::sessionState() : mMuteDirty(false), mParticipantsChanged(false) { - mVoiceFontID = LLUUID(gSavedPerAccountSettings.getString("VoiceFontDefault")); } LLVoiceClient::sessionState::~sessionState() @@ -6757,7 +6800,8 @@ LLVoiceClient::sessionState *LLVoiceClient::addSession(const std::string &uri, c result = new sessionState(); result->mSIPURI = uri; result->mHandle = handle; - + result->mVoiceFontID = LLUUID(gSavedPerAccountSettings.getString("VoiceFontDefault")); + mSessions.insert(result); if(!result->mHandle.empty()) @@ -7166,7 +7210,7 @@ LLVoiceClient::voiceFontEntry::~voiceFontEntry() { } -void LLVoiceClient::deleteAllVoiceFonts() +void LLVoiceClient::deleteVoiceFonts() { mVoiceFontList.clear(); @@ -7178,13 +7222,26 @@ void LLVoiceClient::deleteAllVoiceFonts() mVoiceFontMap.clear(); } +void LLVoiceClient::deleteVoiceFontTemplates() +{ + mVoiceFontTemplateList.clear(); + + voice_font_map_t::iterator iter; + for (iter = mVoiceFontTemplateMap.begin(); iter != mVoiceFontTemplateMap.end(); ++iter) + { + delete iter->second; + } + mVoiceFontTemplateMap.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) + const S32 font_status, + const bool template_font) { // Vivox SessionFontIDs are not guaranteed to remain the same between // sessions or grids so use a UUID for the name. @@ -7202,13 +7259,16 @@ void LLVoiceClient::addVoiceFont(const S32 font_index, voiceFontEntry *font = NULL; + voice_font_map_t& font_map = template_font ? mVoiceFontTemplateMap : mVoiceFontMap; + voice_font_list_t& font_list = template_font ? mVoiceFontTemplateList : mVoiceFontList; + // 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()); + voice_font_map_t::iterator iter = font_map.find(&font_id); + bool duplicate = (iter != font_map.end()); if (duplicate) { LL_DEBUGS("Voice") << "Voice font " << font_index << " duplicates " << iter->second->mFontIndex << "!" << LL_ENDL; @@ -7234,7 +7294,9 @@ void LLVoiceClient::addVoiceFont(const S32 font_index, font->mFontType = font_type; font->mFontStatus = font_status; - LL_DEBUGS("Voice") << "Adding voice font : " << font_id << " (" << font_index << ") : " << name << (has_expired?" (Expired)":"") << LL_ENDL; + LL_DEBUGS("Voice") << (template_font?"Template":"") << ": " << font_id + << " (" << font_index << ") : " << name << (has_expired?" (Expired)":"") + << LL_ENDL; if (font_type < VOICE_FONT_TYPE_NONE || font_type >= VOICE_FONT_TYPE_UNKNOWN) { @@ -7247,23 +7309,16 @@ void LLVoiceClient::addVoiceFont(const S32 font_index, 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))); + font_map.insert(voice_font_map_t::value_type(&(font->mID), font)); + font_list.insert(voice_font_list_t::value_type(&(font->mName), &(font->mID))); } } } bool LLVoiceClient::setVoiceFont(const LLUUID& id) { - return mAudioSession ? setVoiceFont(mAudioSession->mHandle, id) : false; -} - -bool LLVoiceClient::setVoiceFont(const std::string &session_handle, const LLUUID& id) -{ - sessionState *session = findSession(session_handle); - if (!session) + if (!mAudioSession) { - LL_DEBUGS("Voice") << "Invalid Session." << LL_ENDL; return false; } @@ -7285,7 +7340,7 @@ bool LLVoiceClient::setVoiceFont(const std::string &session_handle, const LLUUID // *TODO: Separate voice font defaults for spatial chat and IM? gSavedPerAccountSettings.setString("VoiceFontDefault", id.asString()); - sessionSetVoiceFontSendMessage(session); + sessionSetVoiceFontSendMessage(mAudioSession); notifyVoiceFontObservers(); return true; @@ -7293,13 +7348,7 @@ bool LLVoiceClient::setVoiceFont(const std::string &session_handle, const LLUUID const LLUUID LLVoiceClient::getVoiceFont() { - return mAudioSession ? getVoiceFont(mAudioSession->mHandle) : LLUUID::null; -} - -const LLUUID LLVoiceClient::getVoiceFont(const std::string &session_handle) -{ - sessionState *session = findSession(session_handle); - return session ? session->mVoiceFontID : LLUUID::null; + return mAudioSession ? mAudioSession->mVoiceFontID : LLUUID::null; } S32 LLVoiceClient::getVoiceFontIndex(const LLUUID& id) const @@ -7342,6 +7391,12 @@ void LLVoiceClient::accountGetSessionFontsResponse(int statusCode, const std::st notifyVoiceFontObservers(); } +void LLVoiceClient::accountGetTemplateFontsResponse(int statusCode, const std::string &statusString) +{ + // Voice font list entries were updated via addVoiceFont() during parsing. + notifyVoiceFontObservers(); +} + void LLVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer) { mParticipantObservers.insert(observer); diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index a997f9d500..f0e78580c9 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -444,13 +444,12 @@ static void updatePosition(void); // Voice Fonts bool hasVoiceFonts() const { return !mVoiceFontMap.empty(); }; bool setVoiceFont(const LLUUID& id); - bool setVoiceFont(const std::string &session_handle, const LLUUID& id); const LLUUID getVoiceFont(); - const LLUUID getVoiceFont(const std::string &session_handle); typedef std::multimap<const std::string*, const LLUUID*, stringMapComparitor> voice_font_list_t; const voice_font_list_t &getVoiceFontList() const { return mVoiceFontList; }; + const voice_font_list_t &getVoiceFontTemplateList() const { return mVoiceFontTemplateList; }; void addVoiceFont(const S32 id, const std::string &name, @@ -458,8 +457,10 @@ static void updatePosition(void); const std::string &expiration_date, const bool has_expired, const S32 font_type, - const S32 font_status); + const S32 font_status, + const bool template_font = false); void accountGetSessionFontsResponse(int statusCode, const std::string &statusString); + void accountGetTemplateFontsResponse(int statusCode, const std::string &statusString); ///////////////////////////// // session control messages @@ -483,19 +484,21 @@ 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); void sessionTerminateSendMessage(sessionState *session); void sessionGroupTerminateSendMessage(sessionState *session); void sessionMediaDisconnectSendMessage(sessionState *session); void sessionTextDisconnectSendMessage(sessionState *session); + // Voice font messages + void accountGetSessionFontsSendMessage(); + void accountGetTemplateFontsSendMessage(); + void sessionSetVoiceFontSendMessage(sessionState *session); + // Pokes the state machine to leave the audio session next time around. void sessionTerminate(); @@ -704,7 +707,8 @@ static void updatePosition(void); // Voice Fonts S32 getVoiceFontIndex(const LLUUID& id) const; - void deleteAllVoiceFonts(); + void deleteVoiceFonts(); + void deleteVoiceFontTemplates(); typedef enum e_voice_font_type { @@ -739,6 +743,8 @@ static void updatePosition(void); voice_font_map_t mVoiceFontMap; voice_font_list_t mVoiceFontList; + voice_font_map_t mVoiceFontTemplateMap; + voice_font_list_t mVoiceFontTemplateList; // Audio devices -- cgit v1.2.3 From 270da3e14161d7bf0d53b5f8ebfb9aaf5ad87893 Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Wed, 12 May 2010 02:24:46 +0100 Subject: EXT-7138 WIP Allow selection of no voice font when none are available. --- indra/newview/llvoiceclient.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'indra') diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index e140c6f2ee..d8bf781ce0 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -7322,16 +7322,18 @@ bool LLVoiceClient::setVoiceFont(const LLUUID& id) return false; } - if (!hasVoiceFonts()) - { - LL_DEBUGS("Voice") << "Voice fonts not available." << LL_ENDL; - return false; - } - - if (!id.isNull() && (mVoiceFontMap.find(&id) == mVoiceFontMap.end())) + if (!id.isNull()) { - LL_DEBUGS("Voice") << "Invalid voice font " << id << LL_ENDL; - return false; + if (!hasVoiceFonts()) + { + LL_DEBUGS("Voice") << "Voice fonts not available." << LL_ENDL; + return false; + } + else if (mVoiceFontMap.find(&id) == mVoiceFontMap.end()) + { + LL_DEBUGS("Voice") << "Invalid voice font " << id << LL_ENDL; + return false; + } } // *TODO: Check for expired fonts? -- cgit v1.2.3 From 8aac4348021434ec33e9d8d301310fd7b65f6827 Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Wed, 12 May 2010 02:26:43 +0100 Subject: EXT-7138 WIP Added temporary debug setting "VoiceFontsAvailable", to test UI when no voice fonts are available. --- indra/newview/app_settings/settings.xml | 11 +++++++++++ indra/newview/llvoiceclient.cpp | 10 +++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index e703bd770f..eb07f099b9 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10484,6 +10484,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>VoiceFontsAvailable</key> + <map> + <key>Comment</key> + <string>Temporary debug setting to test UI with no fonts available</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>1</integer> + </map> <key>VoiceFontUI</key> <map> <key>Comment</key> diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index d8bf781ce0..6bc1f42399 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -2318,7 +2318,15 @@ void LLVoiceClient::stateMachine() // request the set of available voice fonts setState(stateVoiceFontsWait); - accountGetSessionFontsSendMessage(); + // *FIX: Remove this temporary setting, used to test UI without fonts + if (gSavedSettings.getBOOL("VoiceFontsAvailable")) + { + accountGetSessionFontsSendMessage(); + } + else + { + setState(stateVoiceFontsReceived); + } accountGetTemplateFontsSendMessage(); // *TODO: Maybe better to do this when opening preview rather than on login // request the current set of block rules (we'll need them when updating the friends list) -- cgit v1.2.3 From 200889bd4b2bef9812051ea644d229d1b40faf30 Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Thu, 13 May 2010 14:59:27 +0100 Subject: EXT-7336 WIP Open the Voice Morphing marketing page from the voice font UI Temporarily points at https://secondlife.com/my/account/voice.php until a proper URL is allocated. --- indra/newview/llpanelvoiceeffect.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra') diff --git a/indra/newview/llpanelvoiceeffect.cpp b/indra/newview/llpanelvoiceeffect.cpp index 4de1fffef9..4d694c1be0 100644 --- a/indra/newview/llpanelvoiceeffect.cpp +++ b/indra/newview/llpanelvoiceeffect.cpp @@ -92,6 +92,7 @@ void LLPanelVoiceEffect::onCommitVoiceEffect() if (value.asInteger() == GET_VOICE_EFFECTS) { LL_DEBUGS("Voice") << "GET VOICE FONTS!" << LL_ENDL; + LLWeb::loadURL(getString("get_voice_effects_url")); } else if (value.asInteger() == PREVIEW_VOICE_EFFECTS) { -- cgit v1.2.3 From f3df31078c48c5a98ce47bf04a14a1938da3bdc8 Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Thu, 13 May 2010 15:09:51 +0100 Subject: EXT-7138 Forgot to rename panel_voice_font.xml to panel_voice_effect.xml oops! --- .../skins/default/xui/en/panel_voice_effect.xml | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 indra/newview/skins/default/xui/en/panel_voice_effect.xml (limited to 'indra') diff --git a/indra/newview/skins/default/xui/en/panel_voice_effect.xml b/indra/newview/skins/default/xui/en/panel_voice_effect.xml new file mode 100644 index 0000000000..dac2f5ebed --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_voice_effect.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<panel + follows="all" + height="26" + layout="topleft" + name="panel_voice_effect" + width="200"> + <string name="no_voice_effect"> + No Voice Effect + </string> + <string name="get_voice_effects_url"> + https://secondlife.com/my/account/voice.php + </string> + <string name="get_voice_effects"> + Add voice effects ▶ + </string> + <string name="preview_voice_effects"> + Preview ▶ + </string> + <combo_box + enabled="false" + follows="left|top|right" + height="23" + name="voice_effect" + top_pad="0" + width="200"> + <combo_box.item + label="No Voice Effect" + name="no_voice_effect" + top_pad="0" + value="0" /> + <combo_box.commit_callback + function="Voice.CommitVoiceEffect" /> + </combo_box> +</panel> -- cgit v1.2.3 From 009db32afecd7e95e6dd37cb8b9899829783a5d4 Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Fri, 14 May 2010 13:11:18 +0100 Subject: EXT-7138 WIP added a refreshVoiceEffectLists() method to LLVoiceEffectInterface --- indra/newview/llpanelvoiceeffect.cpp | 2 +- indra/newview/llpanelvoiceeffect.h | 2 +- indra/newview/llvoiceclient.h | 3 +- indra/newview/llvoicevivox.cpp | 74 +++++++++++++++++++----------------- indra/newview/llvoicevivox.h | 6 ++- 5 files changed, 49 insertions(+), 38 deletions(-) (limited to 'indra') diff --git a/indra/newview/llpanelvoiceeffect.cpp b/indra/newview/llpanelvoiceeffect.cpp index 4d694c1be0..c51ec91b66 100644 --- a/indra/newview/llpanelvoiceeffect.cpp +++ b/indra/newview/llpanelvoiceeffect.cpp @@ -107,7 +107,7 @@ void LLPanelVoiceEffect::onCommitVoiceEffect() } // virtual -void LLPanelVoiceEffect::onVoiceEffectChanged() +void LLPanelVoiceEffect::onVoiceEffectChanged(bool new_effects) { update(); } diff --git a/indra/newview/llpanelvoiceeffect.h b/indra/newview/llpanelvoiceeffect.h index f1a746e288..3ecdcb0d8a 100644 --- a/indra/newview/llpanelvoiceeffect.h +++ b/indra/newview/llpanelvoiceeffect.h @@ -56,7 +56,7 @@ private: void update(); /// Called by voice effect provider when voice effect list is changed. - virtual void onVoiceEffectChanged(); + virtual void onVoiceEffectChanged(bool new_effects); // Fixed entries in the voice effect list typedef enum e_voice_effect_combo_items diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 44da7bcf93..d4f1423f00 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -266,7 +266,7 @@ class LLVoiceEffectObserver { public: virtual ~LLVoiceEffectObserver() { } - virtual void onVoiceEffectChanged() = 0; + virtual void onVoiceEffectChanged(bool new_effects) = 0; }; typedef std::multimap<const std::string, const LLUUID, LLDictionaryLess> voice_effect_list_t; @@ -290,6 +290,7 @@ public: virtual bool setVoiceEffect(const LLUUID& id) = 0; virtual const LLUUID getVoiceEffect() = 0; + virtual void refreshVoiceEffectLists(bool clear_lists) = 0; virtual const voice_effect_list_t &getVoiceEffectList() const = 0; virtual const voice_effect_list_t &getVoiceEffectTemplateList() const = 0; //@} diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index a2ea21056d..aa2fa45b6d 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -337,10 +337,10 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() : mVoiceEnabled(false), mWriteInProgress(false), - mLipSyncEnabled(false) - - + mLipSyncEnabled(false), + mVoiceFontsReceived(false), + mVoiceFontsNew(false) { mSpeakerVolume = scale_speaker_volume(0); @@ -1220,13 +1220,12 @@ void LLVivoxVoiceClient::stateMachine() { // request the set of available voice fonts setState(stateVoiceFontsWait); - accountGetSessionFontsSendMessage(); + refreshVoiceEffectLists(true); } else { setState(stateVoiceFontsReceived); } - accountGetTemplateFontsSendMessage(); // *TODO: Maybe better to do this only when opening preview rather than on login // request the current set of block rules (we'll need them when updating the friends list) accountListBlockRulesSendMessage(); @@ -6317,7 +6316,8 @@ LLVivoxVoiceClient::voiceFontEntry::voiceFontEntry(LLUUID& id) : mFontIndex(0), mHasExpired(false), mFontType(VOICE_FONT_TYPE_NONE), - mFontStatus(VOICE_FONT_STATUS_NONE) + mFontStatus(VOICE_FONT_STATUS_NONE), + mIsNew(false) { } @@ -6325,6 +6325,19 @@ LLVivoxVoiceClient::voiceFontEntry::~voiceFontEntry() { } +void LLVivoxVoiceClient::refreshVoiceEffectLists(bool clear_lists) +{ + if (clear_lists) + { + mVoiceFontsReceived = false; + deleteVoiceFonts(); + deleteVoiceFontTemplates(); + } + + accountGetSessionFontsSendMessage(); + accountGetTemplateFontsSendMessage(); +} + void LLVivoxVoiceClient::addVoiceFont(const S32 font_index, const std::string &name, const std::string &description, @@ -6337,7 +6350,7 @@ void LLVivoxVoiceClient::addVoiceFont(const S32 font_index, // 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 + // If received name is not a UUID, fudge one by hashing the name and type. LLUUID font_id; if (LLUUID::validate(name)) { @@ -6353,38 +6366,36 @@ void LLVivoxVoiceClient::addVoiceFont(const S32 font_index, voice_font_map_t& font_map = template_font ? mVoiceFontTemplateMap : mVoiceFontMap; voice_effect_list_t& font_list = template_font ? mVoiceFontTemplateList : mVoiceFontList; - // 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. + // Check whether we've seen this font before and create an entry for it if not. voice_font_map_t::iterator iter = font_map.find(font_id); - bool duplicate = (iter != font_map.end()); - if (duplicate) + bool new_font = (iter == font_map.end()); + if (new_font) { - LL_DEBUGS("Voice") << "Voice font " << font_index << " duplicates " << iter->second->mFontIndex << "!" << LL_ENDL; - - if (!has_expired) - { - font = iter->second; - } + font = new voiceFontEntry(font_id); } else { - font = new voiceFontEntry(font_id); + font = iter->second; } if (font) { font->mFontIndex = font_index; // Use the description for the human readable name if available, as the - // "name" will probably be a UUID. + // "name" may 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; + // Only flag it as a new font if we have already seen the font list. + if (!template_font && mVoiceFontsReceived && new_font) + { + font->mIsNew = true; + mVoiceFontsNew = true; + } + LL_DEBUGS("Voice") << (template_font?"Template: ":"") << font_id << " (" << font_index << ") : " << name << (has_expired?" (Expired)":"") << LL_ENDL; @@ -6398,7 +6409,7 @@ void LLVivoxVoiceClient::addVoiceFont(const S32 font_index, LL_DEBUGS("Voice") << "Unknown voice font status: " << font_status << LL_ENDL; } - if (!duplicate) + if (new_font) { font_map.insert(voice_font_map_t::value_type(font->mID, font)); font_list.insert(voice_effect_list_t::value_type(font->mName, font->mID)); @@ -6507,7 +6518,10 @@ void LLVivoxVoiceClient::accountGetSessionFontsResponse(int statusCode, const st { setState(stateVoiceFontsReceived); } - notifyVoiceFontObservers(); + mVoiceFontsReceived = true; + + notifyVoiceFontObservers(mVoiceFontsNew); + mVoiceFontsNew = false; } void LLVivoxVoiceClient::accountGetTemplateFontsResponse(int statusCode, const std::string &statusString) @@ -6525,14 +6539,14 @@ void LLVivoxVoiceClient::removeObserver(LLVoiceEffectObserver* observer) mVoiceFontObservers.erase(observer); } -void LLVivoxVoiceClient::notifyVoiceFontObservers() +void LLVivoxVoiceClient::notifyVoiceFontObservers(bool new_fonts) { for (voice_font_observer_set_t::iterator it = mVoiceFontObservers.begin(); it != mVoiceFontObservers.end(); ) { LLVoiceEffectObserver* observer = *it; - observer->onVoiceEffectChanged(); + observer->onVoiceEffectChanged(new_fonts); // In case onVoiceEffectChanged() deleted an entry. it = mVoiceFontObservers.upper_bound(observer); } @@ -6755,10 +6769,6 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr) { LLVivoxVoiceClient::getInstance()->deleteAllAutoAcceptRules(); } - else if (!stricmp("SessionFonts", tag)) - { - LLVivoxVoiceClient::getInstance()->deleteVoiceFonts(); - } else if (!stricmp("SessionFont", tag)) { id = 0; @@ -6769,10 +6779,6 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr) fontType = 0; fontStatus = 0; } - else if (!stricmp("TemplateFonts", tag)) - { - LLVivoxVoiceClient::getInstance()->deleteVoiceFontTemplates(); - } else if (!stricmp("TemplateFont", tag)) { id = 0; diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index 4d18a897c7..fcf8eaf3e9 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -241,6 +241,7 @@ public: virtual bool setVoiceEffect(const LLUUID& id); virtual const LLUUID getVoiceEffect(); + virtual void refreshVoiceEffectLists(bool clear_lists); virtual const voice_effect_list_t &getVoiceEffectList() const { return mVoiceFontList; }; virtual const voice_effect_list_t &getVoiceEffectTemplateList() const { return mVoiceFontTemplateList; }; //@} @@ -848,7 +849,7 @@ private: void accountGetTemplateFontsSendMessage(); void sessionSetVoiceFontSendMessage(sessionState *session); - void notifyVoiceFontObservers(); + void notifyVoiceFontObservers(bool new_fonts = false); typedef enum e_voice_font_type { @@ -878,8 +879,11 @@ private: bool mHasExpired; S32 mFontType; S32 mFontStatus; + bool mIsNew; }; + bool mVoiceFontsReceived; + bool mVoiceFontsNew; voice_effect_list_t mVoiceFontList; voice_effect_list_t mVoiceFontTemplateList; -- cgit v1.2.3 From 110995427fecaf59b4e7885893243a3bb07000db Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Tue, 18 May 2010 14:07:35 +0100 Subject: EXT-7138 WIP Moved implementation of LLVivoxVoiceClient::getVoiceEffectList() and LLVivoxVoiceClient::getVoiceEffectTemplateList() out of the header file --- indra/newview/llvoicevivox.cpp | 10 ++++++++++ indra/newview/llvoicevivox.h | 6 ++---- 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'indra') diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index aa2fa45b6d..2fba8e7b5f 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -6338,6 +6338,16 @@ void LLVivoxVoiceClient::refreshVoiceEffectLists(bool clear_lists) accountGetTemplateFontsSendMessage(); } +const voice_effect_list_t& LLVivoxVoiceClient::getVoiceEffectList() const +{ + return mVoiceFontList; +} + +const voice_effect_list_t& LLVivoxVoiceClient::getVoiceEffectTemplateList() const +{ + return mVoiceFontTemplateList; +} + void LLVivoxVoiceClient::addVoiceFont(const S32 font_index, const std::string &name, const std::string &description, diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index fcf8eaf3e9..39db87b6bd 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -242,8 +242,8 @@ public: virtual const LLUUID getVoiceEffect(); virtual void refreshVoiceEffectLists(bool clear_lists); - virtual const voice_effect_list_t &getVoiceEffectList() const { return mVoiceFontList; }; - virtual const voice_effect_list_t &getVoiceEffectTemplateList() const { return mVoiceFontTemplateList; }; + virtual const voice_effect_list_t& getVoiceEffectList() const; + virtual const voice_effect_list_t& getVoiceEffectTemplateList() const; //@} ////////////////////////////// @@ -455,8 +455,6 @@ protected: void tuningCaptureStartSendMessage(int duration); void tuningCaptureStopSendMessage(); - bool inTuningStates(); - //---------------------------------- // devices void clearCaptureDevices(); -- cgit v1.2.3 From 75f6e32f8836b008485ff65a17c2393696aa8fee Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Tue, 18 May 2010 14:12:54 +0100 Subject: EXT-7337 WIP Added capture buffer for previewing voice fonts to the voice client. --- indra/newview/llvoiceclient.h | 12 +++ indra/newview/llvoicevivox.cpp | 233 ++++++++++++++++++++++++++++++++++++++++- indra/newview/llvoicevivox.h | 30 ++++++ 3 files changed, 272 insertions(+), 3 deletions(-) (limited to 'indra') diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index d4f1423f00..8d898378d6 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -301,6 +301,18 @@ public: virtual void addObserver(LLVoiceEffectObserver* observer) = 0; virtual void removeObserver(LLVoiceEffectObserver* observer) = 0; //@} + + ////////////////////////////// + /// @name Preview buffer + //@{ + virtual void recordPreviewBuffer(bool enable) = 0; + virtual void playPreviewBuffer(bool enable, const LLUUID& effect_id = LLUUID::null) = 0; + virtual void clearPreviewBuffer() = 0; + + virtual bool isPreviewRecording() = 0; + virtual bool isPreviewReady() = 0; + virtual bool isPreviewPlaying() = 0; + //@} }; diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 2fba8e7b5f..ee67879d3d 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -340,7 +340,10 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() : mLipSyncEnabled(false), mVoiceFontsReceived(false), - mVoiceFontsNew(false) + mVoiceFontsNew(false), + + mCaptureBufferRecording(false), + mCaptureBufferPlaying(false) { mSpeakerVolume = scale_speaker_volume(0); @@ -643,6 +646,11 @@ std::string LLVivoxVoiceClient::state2string(LLVivoxVoiceClient::state inState) CASE(stateMicTuningStart); CASE(stateMicTuningRunning); CASE(stateMicTuningStop); + CASE(stateCaptureBufferPaused); + CASE(stateCaptureBufferRecStart); + CASE(stateCaptureBufferRecording); + CASE(stateCaptureBufferPlayStart); + CASE(stateCaptureBufferPlaying); CASE(stateConnectorStart); CASE(stateConnectorStarting); CASE(stateConnectorStarted); @@ -1119,8 +1127,62 @@ void LLVivoxVoiceClient::stateMachine() } break; - - //MARK: stateConnectorStart + + //MARK: stateCaptureBufferPaused + case stateCaptureBufferPaused: + if (mCaptureBufferRecording) + { + setState(stateCaptureBufferRecStart); + // Update UI, should really be separated from the VoiceFont callback + notifyVoiceFontObservers(); + } + else if (mCaptureBufferPlaying) + { + setState(stateCaptureBufferPlayStart); + notifyVoiceFontObservers(); + } + else if (mCaptureBufferClear) + { + mCaptureBufferClear = false; + setState(stateNoChannel); + } + break; + + //MARK: stateCaptureBufferRecStart + case stateCaptureBufferRecStart: + captureBufferRecordStartSendMessage(); + setState(stateCaptureBufferRecording); + break; + + //MARK: stateCaptureBufferRecording + case stateCaptureBufferRecording: + if (!mCaptureBufferRecording || mCaptureBufferPlaying || mCaptureBufferClear) + { + mCaptureBufferRecording = false; + captureBufferRecordStopSendMessage(); + setState(stateCaptureBufferPaused); + notifyVoiceFontObservers(); + } + break; + + //MARK: stateCaptureBufferPlayStart + case stateCaptureBufferPlayStart: + captureBufferPlayStartSendMessage(mPreviewVoiceFontID); + setState(stateCaptureBufferPlaying); + break; + + //MARK: stateCaptureBufferPlaying + case stateCaptureBufferPlaying: + if (!mCaptureBufferPlaying || mCaptureBufferRecording || mCaptureBufferClear) + { + mCaptureBufferPlaying = false; + captureBufferPlayStopSendMessage(); + setState(stateCaptureBufferPaused); + notifyVoiceFontObservers(); + } + break; + + //MARK: stateConnectorStart case stateConnectorStart: if(!mVoiceEnabled) { @@ -1320,6 +1382,11 @@ void LLVivoxVoiceClient::stateMachine() mTuningExitState = stateNoChannel; setState(stateMicTuningStart); } + else if(mCaptureBufferRecording) + { + mTuningExitState = stateNoChannel; + setState(stateCaptureBufferRecStart); + } else if(sessionNeedsRelog(mNextAudioSession)) { requestRelog(); @@ -6562,6 +6629,163 @@ void LLVivoxVoiceClient::notifyVoiceFontObservers(bool new_fonts) } } +void LLVivoxVoiceClient::recordPreviewBuffer(bool enable) +{ + if (enable) + { + mCaptureBufferRecording = true; + LL_DEBUGS("Voice") << "Starting recording" << LL_ENDL; + if(getState() >= stateNoChannel) + { + LL_DEBUGS("Voice") << "no channel" << LL_ENDL; + sessionTerminate(); + } + } + else + { + mCaptureBufferRecording = false; + } +} + +void LLVivoxVoiceClient::playPreviewBuffer(bool enable, const LLUUID& effect_id) +{ + if (enable && !isPreviewReady()) + { + LL_DEBUGS("Voice") << "No preview buffer to play" << LL_ENDL; + return; + } + + mCaptureBufferPlaying = enable; + if (mCaptureBufferPlaying) + { + mPreviewVoiceFontID = effect_id; + } +} + +void LLVivoxVoiceClient::clearPreviewBuffer() +{ + mCaptureBufferClear = true; +} + +bool LLVivoxVoiceClient::isPreviewRecording() +{ + return mCaptureBufferRecording; +} + +bool LLVivoxVoiceClient::isPreviewReady() +{ + state preview_state = getState(); + switch (preview_state) + { + case stateCaptureBufferPaused: + case stateCaptureBufferRecording: + case stateCaptureBufferPlaying: + return true; + break; + default: + return false; + break; + } +} + +bool LLVivoxVoiceClient::isPreviewPlaying() +{ + return mCaptureBufferPlaying; +} + +void LLVivoxVoiceClient::captureBufferRecordStartSendMessage() +{ if(!mAccountHandle.empty()) + { + std::ostringstream stream; + + LL_DEBUGS("Voice") << "Starting audio capture to buffer." << LL_ENDL; + + // Start capture + stream + << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.StartBufferCapture.1\">" + << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" + << "</Request>" + << "\n\n\n"; + + // Unmute the mic + stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Connector.MuteLocalMic.1\">" + << "<ConnectorHandle>" << mConnectorHandle << "</ConnectorHandle>" + << "<Value>false</Value>" + << "</Request>\n\n\n"; + + // Dirty the PTT state so that it will get reset when we finishing previewing + mPTTDirty = true; + + writeString(stream.str()); + } +} + +void LLVivoxVoiceClient::captureBufferRecordStopSendMessage() +{ + if(!mAccountHandle.empty()) + { + std::ostringstream stream; + + LL_DEBUGS("Voice") << "Stopping audio capture to buffer." << LL_ENDL; + + // Mute the mic. PTT state was dirtied at recording start, so will be reset when finished previewing. + stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Connector.MuteLocalMic.1\">" + << "<ConnectorHandle>" << mConnectorHandle << "</ConnectorHandle>" + << "<Value>true</Value>" + << "</Request>\n\n\n"; + + // Stop capture + stream + << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.CaptureAudioStop.1\">" + << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" + << "</Request>" + << "\n\n\n"; + + writeString(stream.str()); + } +} + +void LLVivoxVoiceClient::captureBufferPlayStartSendMessage(const LLUUID& voice_font_id) +{ + if(!mAccountHandle.empty()) + { + std::ostringstream stream; + + LL_DEBUGS("Voice") << "Starting audio buffer playback." << LL_ENDL; + + S32 font_index = getVoiceFontIndex(voice_font_id); + LL_DEBUGS("Voice") << "With voice font: " << voice_font_id << " (" << font_index << ")" << LL_ENDL; + + stream + << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.PlayAudioBuffer.1\">" + << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" + << "<TemplateFontID>" << font_index << "</TemplateFontID>" + << "<FontDelta />" + << "</Request>" + << "\n\n\n"; + + writeString(stream.str()); + } +} + +void LLVivoxVoiceClient::captureBufferPlayStopSendMessage() +{ + if(!mAccountHandle.empty()) + { + std::ostringstream stream; + + LL_DEBUGS("Voice") << "Stopping audio buffer playback." << LL_ENDL; + + stream + << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.RenderAudioStop.1\">" + << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" + << "</Request>" + << "\n\n\n"; + + writeString(stream.str()); + } +} + LLVivoxProtocolParser::LLVivoxProtocolParser() { parser = NULL; @@ -7119,6 +7343,9 @@ void LLVivoxProtocolParser::processResponse(std::string tag) } else if (!stricmp(eventTypeCstr, "AuxAudioPropertiesEvent")) { + // These are really spamming in tuning mode + squelchDebugOutput = true; + LLVivoxVoiceClient::getInstance()->auxAudioPropertiesEvent(energy); } else if (!stricmp(eventTypeCstr, "BuddyPresenceEvent")) diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index 39db87b6bd..6c302962a3 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -253,6 +253,18 @@ public: virtual void removeObserver(LLVoiceEffectObserver* observer); //@} + ////////////////////////////// + /// @name Effect preview buffer + //@{ + virtual void recordPreviewBuffer(bool enable); + virtual void playPreviewBuffer(bool enable, const LLUUID& effect_id = LLUUID::null); + virtual void clearPreviewBuffer(); + + virtual bool isPreviewRecording(); + virtual bool isPreviewReady(); + virtual bool isPreviewPlaying(); + //@} + //@} @@ -373,6 +385,11 @@ protected: stateMicTuningStart, stateMicTuningRunning, stateMicTuningStop, + stateCaptureBufferPaused, + stateCaptureBufferRecStart, + stateCaptureBufferRecording, + stateCaptureBufferPlayStart, + stateCaptureBufferPlaying, stateConnectorStart, // connector needs to be started stateConnectorStarting, // waiting for connector handle stateConnectorStarted, // connector handle received @@ -891,6 +908,19 @@ private: typedef std::set<LLVoiceEffectObserver*> voice_font_observer_set_t; voice_font_observer_set_t mVoiceFontObservers; + + // Audio capture buffer + + void captureBufferRecordStartSendMessage(); + void captureBufferRecordStopSendMessage(); + void captureBufferPlayStartSendMessage(const LLUUID& voice_font_id = LLUUID::null); + void captureBufferPlayStopSendMessage(); + + bool mCaptureBufferRecording; + bool mCaptureBufferPlaying; + bool mCaptureBufferClear; + + LLUUID mPreviewVoiceFontID; }; /** -- cgit v1.2.3 From 24c55c9a689aaf7c8c961a5eb4aab5283b0fb1fa Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Tue, 18 May 2010 14:16:25 +0100 Subject: EXT-7337 WIP Implemented prototype voice font preview floater. --- indra/newview/CMakeLists.txt | 2 + indra/newview/llfloatervoiceeffect.cpp | 172 +++++++++++++++++++++ indra/newview/llfloatervoiceeffect.h | 69 +++++++++ indra/newview/llpanelvoiceeffect.cpp | 10 +- indra/newview/llviewerfloaterreg.cpp | 4 +- .../skins/default/xui/en/floater_voice_effect.xml | 123 +++++++++++++++ 6 files changed, 375 insertions(+), 5 deletions(-) create mode 100644 indra/newview/llfloatervoiceeffect.cpp create mode 100644 indra/newview/llfloatervoiceeffect.h create mode 100644 indra/newview/skins/default/xui/en/floater_voice_effect.xml (limited to 'indra') diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index f2a2a129f8..d400510b91 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -214,6 +214,7 @@ set(viewer_SOURCE_FILES llfloaterurldisplay.cpp llfloaterurlentry.cpp llfloatervoicedevicesettings.cpp + llfloatervoiceeffect.cpp llfloaterwater.cpp llfloaterwhitelistentry.cpp llfloaterwindlight.cpp @@ -731,6 +732,7 @@ set(viewer_HEADER_FILES llfloaterurldisplay.h llfloaterurlentry.h llfloatervoicedevicesettings.h + llfloatervoiceeffect.h llfloaterwater.h llfloaterwhitelistentry.h llfloaterwindlight.h diff --git a/indra/newview/llfloatervoiceeffect.cpp b/indra/newview/llfloatervoiceeffect.cpp new file mode 100644 index 0000000000..5a579f5aeb --- /dev/null +++ b/indra/newview/llfloatervoiceeffect.cpp @@ -0,0 +1,172 @@ +/** + * @file llfloatervoiceeffect.cpp + * @brief Selection and preview of voice effect. + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llfloatervoiceeffect.h" + +#include "llscrolllistctrl.h" +#include "lltrans.h" + +LLFloaterVoiceEffect::LLFloaterVoiceEffect(const LLSD& key) + : LLFloater(key) +{ + mCommitCallbackRegistrar.add("VoiceEffect.Record", boost::bind(&LLFloaterVoiceEffect::onClickRecord, this)); + mCommitCallbackRegistrar.add("VoiceEffect.Play", boost::bind(&LLFloaterVoiceEffect::onClickPlay, this)); +} + +// virtual +LLFloaterVoiceEffect::~LLFloaterVoiceEffect() +{ + if(LLVoiceClient::instanceExists()) + { + LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); + if (effect_interface) + { + effect_interface->removeObserver(this); + } + } +} + +// virtual +BOOL LLFloaterVoiceEffect::postBuild() +{ + setDefaultBtn("record_btn"); + + mVoiceEffectList = getChild<LLScrollListCtrl>("voice_effect_list"); + + LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); + if (effect_interface) + { + effect_interface->addObserver(this); + } + + update(); + + return TRUE; +} + +// virtual +void LLFloaterVoiceEffect::onClose(bool app_quitting) +{ + LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); + if (effect_interface) + { + effect_interface->clearPreviewBuffer(); + } +} + +void LLFloaterVoiceEffect::update() +{ + if (!mVoiceEffectList) + { + return; + } + + LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); + if (!effect_interface) // || !LLVoiceClient::instance().isVoiceWorking()) + { + mVoiceEffectList->setEnabled(false); + return; + } + + 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) + { + LLSD element; + element["id"] = it->second; + element["columns"][1]["column"] = "name"; + element["columns"][1]["value"] = it->first; + mVoiceEffectList->addElement(element, ADD_BOTTOM); + } + } + + mVoiceEffectList->setValue(effect_interface->getVoiceEffect()); + mVoiceEffectList->setEnabled(true); + + bool recording = effect_interface->isPreviewRecording(); + getChild<LLButton>("record_btn")->setVisible(!recording); + getChild<LLButton>("record_stop_btn")->setVisible(recording); + + getChild<LLButton>("play_btn")->setEnabled(effect_interface->isPreviewReady()); + bool playing = effect_interface->isPreviewPlaying(); + getChild<LLButton>("play_btn")->setVisible(!playing); + getChild<LLButton>("play_stop_btn")->setVisible(playing); +} + +// virtual +void LLFloaterVoiceEffect::onVoiceEffectChanged(bool new_effects) +{ + update(); +} + +void LLFloaterVoiceEffect::onClickRecord() +{ + LL_DEBUGS("Voice") << "Record clicked" << LL_ENDL; + LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); + if (effect_interface) // && LLVoiceClient::instance().isVoiceWorking()) + { + bool record = !effect_interface->isPreviewRecording(); + effect_interface->recordPreviewBuffer(record); + getChild<LLButton>("record_btn")->setVisible(!record); + getChild<LLButton>("record_stop_btn")->setVisible(record); + } +} + +void LLFloaterVoiceEffect::onClickPlay() +{ + LL_DEBUGS("Voice") << "Play clicked" << LL_ENDL; + if (!mVoiceEffectList) + { + return; + } + + const LLUUID& effect_id = mVoiceEffectList->getCurrentID(); + + LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); + if (effect_interface) // && LLVoiceClient::instance().isVoiceWorking()) + { + bool play = !effect_interface->isPreviewPlaying(); + effect_interface->playPreviewBuffer(play, effect_id); + getChild<LLButton>("play_btn")->setVisible(!play); + getChild<LLButton>("play_stop_btn")->setVisible(play); + } +} diff --git a/indra/newview/llfloatervoiceeffect.h b/indra/newview/llfloatervoiceeffect.h new file mode 100644 index 0000000000..cd639dba5a --- /dev/null +++ b/indra/newview/llfloatervoiceeffect.h @@ -0,0 +1,69 @@ +/** + * @file llfloatervoiceeffect.h + * @brief Selection and preview of voice effects. + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLFLOATERVOICEEFFECT_H +#define LL_LLFLOATERVOICEEFFECT_H + +#include "llfloater.h" +#include "llvoiceclient.h" + +class LLButton; +class LLScrollListCtrl; + +class LLFloaterVoiceEffect + : public LLFloater + , public LLVoiceEffectObserver +{ +public: + LOG_CLASS(LLFloaterVoiceEffect); + + LLFloaterVoiceEffect(const LLSD& key); + virtual ~LLFloaterVoiceEffect(); + + virtual BOOL postBuild(); + virtual void onClose(bool app_quitting); + +private: + void update(); + + /// Called by voice effect provider when voice effect list is changed. + virtual void onVoiceEffectChanged(bool new_effects); + + void onClickRecord(); + void onClickPlay(); +// void onClickActivate(); + + LLUUID mSelectedID; + LLScrollListCtrl* mVoiceEffectList; +}; + +#endif diff --git a/indra/newview/llpanelvoiceeffect.cpp b/indra/newview/llpanelvoiceeffect.cpp index c51ec91b66..6210fc7cc7 100644 --- a/indra/newview/llpanelvoiceeffect.cpp +++ b/indra/newview/llpanelvoiceeffect.cpp @@ -36,8 +36,8 @@ #include "llpanelvoiceeffect.h" #include "llcombobox.h" +#include "llfloaterreg.h" #include "llpanel.h" -#include "llvoicechannel.h" #include "llvoiceclient.h" static LLRegisterPanelClassWrapper<LLPanelVoiceEffect> t_panel_voice_effect("panel_voice_effect"); @@ -64,7 +64,6 @@ LLPanelVoiceEffect::~LLPanelVoiceEffect() BOOL LLPanelVoiceEffect::postBuild() { mVoiceEffectCombo = getChild<LLComboBox>("voice_effect"); - update(); LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); if (effect_interface) @@ -72,6 +71,8 @@ BOOL LLPanelVoiceEffect::postBuild() effect_interface->addObserver(this); } + update(); + return TRUE; } @@ -91,12 +92,13 @@ void LLPanelVoiceEffect::onCommitVoiceEffect() LLSD value = mVoiceEffectCombo->getValue(); if (value.asInteger() == GET_VOICE_EFFECTS) { - LL_DEBUGS("Voice") << "GET VOICE FONTS!" << LL_ENDL; + // Open the voice morphing info web page LLWeb::loadURL(getString("get_voice_effects_url")); } else if (value.asInteger() == PREVIEW_VOICE_EFFECTS) { - LL_DEBUGS("Voice") << "PREVIEW VOICE FONTS!" << LL_ENDL; + // Open the voice effects management floater + LLFloaterReg::showInstance("voice_effect"); } else { diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 506cebfe73..c4a5d6e3fd 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -102,6 +102,7 @@ #include "llfloateruipreview.h" #include "llfloaterurldisplay.h" #include "llfloatervoicedevicesettings.h" +#include "llfloatervoiceeffect.h" #include "llfloaterwater.h" #include "llfloaterwhitelistentry.h" #include "llfloaterwindlight.h" @@ -253,7 +254,8 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundPreview>, "upload"); LLFloaterReg::add("voice_controls", "floater_voice_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLCallFloater>); - + LLFloaterReg::add("voice_effect", "floater_voice_effect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterVoiceEffect>); + LLFloaterReg::add("whitelist_entry", "floater_whitelist_entry.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWhiteListEntry>); LLFloaterWindowSizeUtil::registerFloater(); LLFloaterReg::add("world_map", "floater_world_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWorldMap>); diff --git a/indra/newview/skins/default/xui/en/floater_voice_effect.xml b/indra/newview/skins/default/xui/en/floater_voice_effect.xml new file mode 100644 index 0000000000..5627eb3aff --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_voice_effect.xml @@ -0,0 +1,123 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + legacy_header_height="18" + can_resize="true" + height="465" + name="voice_effects" + help_topic="voice_effects" + title="VOICE EFFECTS" + background_visible="true" + follows="all" + label="Places" + layout="topleft" + min_height="350" + min_width="240" + width="313"> + <string name="no_voice_effect"> + No Voice Effect + </string> + <scroll_list + bottom_delta="400" + draw_heading="true" + follows="all" + layout="topleft" + left="0" + multi_select="false" + top="20" + name="voice_effect_list"> + <scroll_list.columns + label="New" + name="new" + width="48" /> + <scroll_list.columns + label="Name" + name="name" + width="153" /> + <scroll_list.columns + label="Expires" + name="expires" + width="100" /> + <scroll_list.columns + label="" + name="key" + width="-1" /> + </scroll_list> + <panel + background_visible="true" + bevel_style="none" + top_pad="0" + follows="left|right|bottom" + height="30" + label="bottom_panel" + layout="topleft" + left="0" + name="bottom_panel" + width="313"> +<!-- + <button + follows="bottom|left" + font="SansSerifBigBold" + height="10" + image_hover_selected="Activate_Checkmark" + image_selected="Activate_Checkmark" + image_unselected="Activate_Checkmark" + layout="topleft" + left="10" + name="activate_btn" + tool_tip="Activate/Deactivate selected voice effect" + top="10" + width="10" + <button.commit_callback + function="VoiceEffect.Activate" /> + </button> +--> + </panel> + <button + follows="left|bottom" + height="23" + label="Record" + layout="topleft" + left="6" + name="record_btn" + top_pad="5" + width="83"> + <button.commit_callback + function="VoiceEffect.Record" /> + </button> + <button + follows="left|bottom" + height="23" + label="Stop" + layout="topleft" + left_delta="0" + name="record_stop_btn" + top_delta="0" + width="83"> + <button.commit_callback + function="VoiceEffect.Record" /> + </button> + <button + follows="left|bottom" + height="23" + label="Play" + layout="topleft" + left_pad="6" + name="play_btn" + top_delta="0" + width="83"> + <button.commit_callback + function="VoiceEffect.Play" /> + </button> + <button + follows="left|bottom" + height="23" + label="Stop" + layout="topleft" + left_delta="0" + name="play_stop_btn" + top_delta="0" + width="83"> + <button.commit_callback + function="VoiceEffect.Play" /> + </button> +</floater> -- cgit v1.2.3 From 04ef90ceb0829e660d9c89a13ef526b3d30c732c Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> 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 <aimee@lindenlab.com> 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 <aimee@lindenlab.com> 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<LLScrollListItem*> items = mVoiceEffectList->getAllSelected(); + for(std::vector<LLScrollListItem*>::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<LLButton>("record_btn")->setVisible(!recording); getChild<LLButton>("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 @@ <string name="no_voice_effect"> No Voice Effect </string> + <string name="new_voice_effect"> + New! + </string> <scroll_list bottom_delta="400" draw_heading="true" @@ -25,24 +28,76 @@ multi_select="false" top="20" name="voice_effect_list"> - <scroll_list.columns - label="New" - name="new" - width="48" /> <scroll_list.columns label="Name" name="name" width="153" /> + <scroll_list.columns + label="New" + name="new" + width="48" /> <scroll_list.columns label="Expires" name="expires" width="100" /> - <scroll_list.columns - label="" - name="key" - width="-1" /> </scroll_list> - <panel + <panel + background_visible="true" + bevel_style="none" + top_pad="0" + follows="left|right|bottom" + height="30" + label="bottom_panel" + layout="topleft" + left="0" + name="bottom_panel" + width="313"> +<!-- + <menu_button + follows="bottom|left" + height="18" + image_disabled="OptionsMenu_Disabled" + image_selected="OptionsMenu_Press" + image_unselected="OptionsMenu_Off" + layout="topleft" + left="10" + menu_filename="menu_voice_effect_gear.xml" + name="gear_btn" + top="5" + tool_tip="More options" + width="18" /> +--> + <button + follows="bottom|left" + font="SansSerifBigBold" + height="18" + image_selected="AddItem_Press" + image_unselected="AddItem_Off" + image_disabled="AddItem_Disabled" + layout="topleft" + left="10" + name="new_gesture_btn" + tool_tip="Make new gesture" + top="5" + width="18" /> + <button + follows="bottom|left" + font="SansSerifBigBold" + height="10" + image_hover_selected="Activate_Checkmark" + image_selected="Activate_Checkmark" + image_unselected="Activate_Checkmark" + layout="topleft" + left_pad="5" + name="activate_btn" + tool_tip="Activate/Deactivate selected voice effect" + top="10" + width="10"> + <button.commit_callback + function="VoiceEffect.Activate" /> + </button> + </panel> +<!-- <panel background_visible="true" bevel_style="none" top_pad="0" @@ -53,7 +108,6 @@ left="0" name="bottom_panel" width="313"> -<!-- <button follows="bottom|left" font="SansSerifBigBold" @@ -70,17 +124,16 @@ <button.commit_callback function="VoiceEffect.Activate" /> </button> ---> - </panel> + </panel> --> <button follows="left|bottom" height="23" - label="Record" + label="Record Sample" layout="topleft" left="6" name="record_btn" top_pad="5" - width="83"> + width="135"> <button.commit_callback function="VoiceEffect.Record" /> </button> @@ -92,19 +145,19 @@ left_delta="0" name="record_stop_btn" top_delta="0" - width="83"> + width="135"> <button.commit_callback function="VoiceEffect.Record" /> </button> <button follows="left|bottom" height="23" - label="Play" + label="Play Preview" layout="topleft" left_pad="6" name="play_btn" top_delta="0" - width="83"> + width="135"> <button.commit_callback function="VoiceEffect.Play" /> </button> @@ -116,7 +169,7 @@ left_delta="0" name="play_stop_btn" top_delta="0" - width="83"> + width="135"> <button.commit_callback function="VoiceEffect.Play" /> </button> -- cgit v1.2.3 From 2930b805d3a5aa88efdbe9eadfec210c461edfa9 Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Wed, 19 May 2010 17:35:53 +0100 Subject: EXT-7337 WIP Fix formatting in floater_voice_effect.xml (no functional change) --- .../skins/default/xui/en/floater_voice_effect.xml | 48 +++++++++++----------- 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'indra') 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 8f2f13dffe..8452fb55b7 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_effect.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_effect.xml @@ -41,31 +41,31 @@ name="expires" width="100" /> </scroll_list> - <panel - background_visible="true" - bevel_style="none" - top_pad="0" - follows="left|right|bottom" - height="30" - label="bottom_panel" - layout="topleft" - left="0" - name="bottom_panel" - width="313"> + <panel + background_visible="true" + bevel_style="none" + top_pad="0" + follows="left|right|bottom" + height="30" + label="bottom_panel" + layout="topleft" + left="0" + name="bottom_panel" + width="313"> <!-- - <menu_button - follows="bottom|left" - height="18" - image_disabled="OptionsMenu_Disabled" - image_selected="OptionsMenu_Press" - image_unselected="OptionsMenu_Off" - layout="topleft" - left="10" - menu_filename="menu_voice_effect_gear.xml" - name="gear_btn" - top="5" - tool_tip="More options" - width="18" /> + <menu_button + follows="bottom|left" + height="18" + image_disabled="OptionsMenu_Disabled" + image_selected="OptionsMenu_Press" + image_unselected="OptionsMenu_Off" + layout="topleft" + left="10" + menu_filename="menu_voice_effect_gear.xml" + name="gear_btn" + top="5" + tool_tip="More options" + width="18" /> --> <button follows="bottom|left" -- cgit v1.2.3 From 4c6d743665ae39a6402ee7b86f43043cb4c5806d Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Wed, 19 May 2010 21:13:19 +0100 Subject: EXT-7337 WIP Voice font previewing Handle mediaCompletionEvents in the voice client to update UI when preview playback ends. --- indra/newview/llvoicevivox.cpp | 38 ++++++++++++++++++++++++++++++++++++-- indra/newview/llvoicevivox.h | 2 ++ 2 files changed, 38 insertions(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 2df9152a17..7daf865151 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -3530,6 +3530,22 @@ void LLVivoxVoiceClient::accountLoginStateChangeEvent( } } +void LLVivoxVoiceClient::mediaCompletionEvent(std::string &sessionGroupHandle, std::string &mediaCompletionType) +{ + if (mediaCompletionType == "AuxBufferAudioCapture") + { + mCaptureBufferRecording = false; + } + else if (mediaCompletionType == "AuxBufferAudioRender") + { + mCaptureBufferPlaying = false; + } + else + { + LL_DEBUGS("Voice") << "Unknown MediaCompletionType: " << mediaCompletionType << LL_ENDL; + } +} + void LLVivoxVoiceClient::mediaStreamUpdatedEvent( std::string &sessionHandle, std::string &sessionGroupHandle, @@ -7071,6 +7087,10 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr) fontType = 0; fontStatus = 0; } + else if (!stricmp("MediaCompletionType", tag)) + { + mediaCompletionType.clear(); + } } } responseDepth++; @@ -7248,7 +7268,11 @@ void LLVivoxProtocolParser::EndTag(const char *tag) { fontStatus = strtol(string.c_str(), NULL, 10); } - + else if (!stricmp("MediaCompletionType", tag)) + { + mediaCompletionType = string;; + } + textBuffer.clear(); accumulateText= false; @@ -7330,7 +7354,17 @@ void LLVivoxProtocolParser::processResponse(std::string tag) </Event> */ LLVivoxVoiceClient::getInstance()->mediaStreamUpdatedEvent(sessionHandle, sessionGroupHandle, statusCode, statusString, state, incoming); - } + } + else if (!stricmp(eventTypeCstr, "MediaCompletionEvent")) + { + /* + <Event type="MediaCompletionEvent"> + <SessionGroupHandle /> + <MediaCompletionType>AuxBufferAudioCapture</MediaCompletionType> + </Event> + */ + LLVivoxVoiceClient::getInstance()->mediaCompletionEvent(sessionGroupHandle, mediaCompletionType); + } else if (!stricmp(eventTypeCstr, "TextStreamUpdatedEvent")) { /* diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index 1047d2e5ed..5ba8082d56 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -499,6 +499,7 @@ protected: void connectorShutdownResponse(int statusCode, std::string &statusString); void accountLoginStateChangeEvent(std::string &accountHandle, int statusCode, std::string &statusString, int state); + void mediaCompletionEvent(std::string &sessionGroupHandle, std::string &mediaCompletionType); void mediaStreamUpdatedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, int statusCode, std::string &statusString, int state, bool incoming); void textStreamUpdatedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, bool enabled, int state, bool incoming); void sessionAddedEvent(std::string &uriString, std::string &alias, std::string &sessionHandle, std::string &sessionGroupHandle, bool isChannel, bool incoming, std::string &nameString, std::string &applicationString); @@ -1015,6 +1016,7 @@ protected: bool hasExpired; S32 fontType; S32 fontStatus; + std::string mediaCompletionType; // Members for processing text between tags std::string textBuffer; -- cgit v1.2.3 From 4f2f2f90378e5191cd00748c2cc6633af3efd230 Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Wed, 19 May 2010 21:14:24 +0100 Subject: EXT-7138 WIP Enable activation of voice effects from the Voice Effects floater --- indra/newview/llfloatervoiceeffect.cpp | 28 +++++++++++++++++++--- indra/newview/llfloatervoiceeffect.h | 3 ++- .../skins/default/xui/en/floater_voice_effect.xml | 12 +++++++--- 3 files changed, 36 insertions(+), 7 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloatervoiceeffect.cpp b/indra/newview/llfloatervoiceeffect.cpp index de12e8d12a..60831936ca 100644 --- a/indra/newview/llfloatervoiceeffect.cpp +++ b/indra/newview/llfloatervoiceeffect.cpp @@ -36,12 +36,15 @@ #include "llscrolllistctrl.h" #include "lltrans.h" +#include "llweb.h" LLFloaterVoiceEffect::LLFloaterVoiceEffect(const LLSD& key) : LLFloater(key) { mCommitCallbackRegistrar.add("VoiceEffect.Record", boost::bind(&LLFloaterVoiceEffect::onClickRecord, this)); mCommitCallbackRegistrar.add("VoiceEffect.Play", boost::bind(&LLFloaterVoiceEffect::onClickPlay, this)); + mCommitCallbackRegistrar.add("VoiceEffect.Add", boost::bind(&LLFloaterVoiceEffect::onClickAdd, this)); + mCommitCallbackRegistrar.add("VoiceEffect.Activate", boost::bind(&LLFloaterVoiceEffect::onClickActivate, this)); } // virtual @@ -63,6 +66,10 @@ BOOL LLFloaterVoiceEffect::postBuild() setDefaultBtn("record_btn"); mVoiceEffectList = getChild<LLScrollListCtrl>("voice_effect_list"); + if (mVoiceEffectList) + { + mVoiceEffectList->setDoubleClickCallback(boost::bind(&LLFloaterVoiceEffect::onClickActivate, this)); + } LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); if (effect_interface) @@ -93,7 +100,7 @@ void LLFloaterVoiceEffect::update() } LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); - if (!effect_interface) // || !LLVoiceClient::instance().isVoiceWorking()) + if (!effect_interface) { mVoiceEffectList->setEnabled(false); return; @@ -207,7 +214,7 @@ void LLFloaterVoiceEffect::onClickRecord() { LL_DEBUGS("Voice") << "Record clicked" << LL_ENDL; LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); - if (effect_interface) // && LLVoiceClient::instance().isVoiceWorking()) + if (effect_interface) { bool record = !effect_interface->isPreviewRecording(); effect_interface->recordPreviewBuffer(record); @@ -227,7 +234,7 @@ void LLFloaterVoiceEffect::onClickPlay() const LLUUID& effect_id = mVoiceEffectList->getCurrentID(); LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); - if (effect_interface) // && LLVoiceClient::instance().isVoiceWorking()) + if (effect_interface) { bool play = !effect_interface->isPreviewPlaying(); effect_interface->playPreviewBuffer(play, effect_id); @@ -235,3 +242,18 @@ void LLFloaterVoiceEffect::onClickPlay() getChild<LLButton>("play_stop_btn")->setVisible(play); } } + +void LLFloaterVoiceEffect::onClickAdd() +{ + // Open the voice morphing info web page + LLWeb::loadURL(getString("get_voice_effects_url")); +} + +void LLFloaterVoiceEffect::onClickActivate() +{ + LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); + if (effect_interface && mVoiceEffectList) + { + effect_interface->setVoiceEffect(mVoiceEffectList->getCurrentID()); + } +} diff --git a/indra/newview/llfloatervoiceeffect.h b/indra/newview/llfloatervoiceeffect.h index cd639dba5a..5ad64f0e26 100644 --- a/indra/newview/llfloatervoiceeffect.h +++ b/indra/newview/llfloatervoiceeffect.h @@ -60,7 +60,8 @@ private: void onClickRecord(); void onClickPlay(); -// void onClickActivate(); + void onClickAdd(); + void onClickActivate(); LLUUID mSelectedID; LLScrollListCtrl* mVoiceEffectList; 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 8452fb55b7..1f28a6375f 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 @@ <string name="no_voice_effect"> No Voice Effect </string> + <string name="get_voice_effects_url"> + https://secondlife.com/my/account/voice.php + </string> <string name="new_voice_effect"> New! </string> @@ -76,10 +79,13 @@ image_disabled="AddItem_Disabled" layout="topleft" left="10" - name="new_gesture_btn" - tool_tip="Make new gesture" + name="add_voice_effect_btn" + tool_tip="Get more voice effects" top="5" - width="18" /> + width="18"> + <button.commit_callback + function="VoiceEffect.Add" /> + </button> <button follows="bottom|left" font="SansSerifBigBold" -- cgit v1.2.3 From 1a88cb1c392f4f1274db88a8d2cdd35ad6028838 Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Wed, 19 May 2010 21:25:41 +0100 Subject: CSX-1753 WIP Set temporary Voice Morphing marketing URL for testing. Set to http://secondlife.com/landing/v0icem0rphingt3st Needs updating to http://secondlife.com/voicemorphing before launch. --- indra/newview/skins/default/xui/en/floater_voice_effect.xml | 2 +- indra/newview/skins/default/xui/en/panel_voice_effect.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'indra') 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 1f28a6375f..82f816fec1 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_effect.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_effect.xml @@ -17,7 +17,7 @@ No Voice Effect </string> <string name="get_voice_effects_url"> - https://secondlife.com/my/account/voice.php + http://secondlife.com/landing/v0icem0rphingt3st </string> <string name="new_voice_effect"> New! diff --git a/indra/newview/skins/default/xui/en/panel_voice_effect.xml b/indra/newview/skins/default/xui/en/panel_voice_effect.xml index dac2f5ebed..dbcb7b64f7 100644 --- a/indra/newview/skins/default/xui/en/panel_voice_effect.xml +++ b/indra/newview/skins/default/xui/en/panel_voice_effect.xml @@ -9,7 +9,7 @@ No Voice Effect </string> <string name="get_voice_effects_url"> - https://secondlife.com/my/account/voice.php + http://secondlife.com/landing/v0icem0rphingt3st </string> <string name="get_voice_effects"> Add voice effects ▶ -- cgit v1.2.3 From b0b07b9438a8c90e4f8f68743310354b28583d5e Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Thu, 20 May 2010 22:55:47 +0100 Subject: EXT-7138 WIP Voice Morphing - Reselect "No voice effect" correctly in the voice effect combo if "Preview" or "Add effects" is chosen while no effects are enabled. --- indra/newview/llpanelvoiceeffect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llpanelvoiceeffect.cpp b/indra/newview/llpanelvoiceeffect.cpp index 6210fc7cc7..daafb451e0 100644 --- a/indra/newview/llpanelvoiceeffect.cpp +++ b/indra/newview/llpanelvoiceeffect.cpp @@ -126,7 +126,7 @@ void LLPanelVoiceEffect::update() } mVoiceEffectCombo->removeall(); - mVoiceEffectCombo->add(getString("no_voice_effect"), NO_VOICE_EFFECT); + mVoiceEffectCombo->add(getString("no_voice_effect"), LLUUID::null); mVoiceEffectCombo->addSeparator(); const voice_effect_list_t& effect_list = effect_interface->getVoiceEffectList(); -- cgit v1.2.3 From 927977c5d84473bc9d7c47c767dbdd71951c0267 Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Fri, 21 May 2010 18:14:29 +0100 Subject: EXT-7138 WIP Voice Morphing - Added a "My Voice" item to the "Me" menu. --- indra/newview/skins/default/xui/en/menu_viewer.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'indra') diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 16c2581d63..5425c545e0 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -80,6 +80,16 @@ function="Floater.Toggle" parameter="gestures" /> </menu_item_check> + <menu_item_check + label="My Voice" + name="ShowVoice"> + <menu_item_check.on_check + function="Floater.Visible" + parameter="voice_effect" /> + <menu_item_check.on_click + function="Floater.Toggle" + parameter="voice_effect" /> + </menu_item_check> <menu label="My Status" name="Status" -- cgit v1.2.3 From 05157c9985d955bb62c9ef897cee6298500c762d Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Sat, 22 May 2010 15:24:08 +0100 Subject: EXT-7138 WIP Voice Morphing Updated "Preview Voice Morphing" and "Get Voice Morphing" items in the Voice Effect combo --- indra/newview/llpanelvoiceeffect.cpp | 14 +++++++------- indra/newview/llpanelvoiceeffect.h | 4 ++-- .../newview/skins/default/xui/en/floater_voice_effect.xml | 2 +- indra/newview/skins/default/xui/en/panel_voice_effect.xml | 8 ++++---- 4 files changed, 14 insertions(+), 14 deletions(-) (limited to 'indra') diff --git a/indra/newview/llpanelvoiceeffect.cpp b/indra/newview/llpanelvoiceeffect.cpp index daafb451e0..915d547056 100644 --- a/indra/newview/llpanelvoiceeffect.cpp +++ b/indra/newview/llpanelvoiceeffect.cpp @@ -90,16 +90,16 @@ void LLPanelVoiceEffect::onCommitVoiceEffect() } LLSD value = mVoiceEffectCombo->getValue(); - if (value.asInteger() == GET_VOICE_EFFECTS) - { - // Open the voice morphing info web page - LLWeb::loadURL(getString("get_voice_effects_url")); - } - else if (value.asInteger() == PREVIEW_VOICE_EFFECTS) + if (value.asInteger() == PREVIEW_VOICE_EFFECTS) { // Open the voice effects management floater LLFloaterReg::showInstance("voice_effect"); } + else if (value.asInteger() == GET_VOICE_EFFECTS) + { + // Open the voice morphing info web page + LLWeb::loadURL(getString("get_voice_effects_url")); + } else { effect_interface->setVoiceEffect(value.asUUID()); @@ -140,8 +140,8 @@ void LLPanelVoiceEffect::update() mVoiceEffectCombo->addSeparator(); } - mVoiceEffectCombo->add(getString("get_voice_effects"), GET_VOICE_EFFECTS); mVoiceEffectCombo->add(getString("preview_voice_effects"), PREVIEW_VOICE_EFFECTS); + mVoiceEffectCombo->add(getString("get_voice_effects"), GET_VOICE_EFFECTS); mVoiceEffectCombo->setValue(effect_interface->getVoiceEffect()); mVoiceEffectCombo->setEnabled(true); diff --git a/indra/newview/llpanelvoiceeffect.h b/indra/newview/llpanelvoiceeffect.h index 3ecdcb0d8a..008123a4e4 100644 --- a/indra/newview/llpanelvoiceeffect.h +++ b/indra/newview/llpanelvoiceeffect.h @@ -62,8 +62,8 @@ private: typedef enum e_voice_effect_combo_items { NO_VOICE_EFFECT = 0, - GET_VOICE_EFFECTS = 1, - PREVIEW_VOICE_EFFECTS = 2 + PREVIEW_VOICE_EFFECTS = 1, + GET_VOICE_EFFECTS = 2 } EVoiceEffectComboItems; LLComboBox* mVoiceEffectCombo; 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 82f816fec1..d869f6c610 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_effect.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_effect.xml @@ -5,7 +5,7 @@ height="465" name="voice_effects" help_topic="voice_effects" - title="VOICE EFFECTS" + title="PREVIEW VOICE MORPHING" background_visible="true" follows="all" label="Places" diff --git a/indra/newview/skins/default/xui/en/panel_voice_effect.xml b/indra/newview/skins/default/xui/en/panel_voice_effect.xml index dbcb7b64f7..9e5652d1e2 100644 --- a/indra/newview/skins/default/xui/en/panel_voice_effect.xml +++ b/indra/newview/skins/default/xui/en/panel_voice_effect.xml @@ -11,11 +11,11 @@ <string name="get_voice_effects_url"> http://secondlife.com/landing/v0icem0rphingt3st </string> - <string name="get_voice_effects"> - Add voice effects ▶ - </string> <string name="preview_voice_effects"> - Preview ▶ + Preview Voice Morphing ▶ + </string> + <string name="get_voice_effects"> + Get Voice Morphing ▶ </string> <combo_box enabled="false" -- cgit v1.2.3 From 5cf632aacbae683676c341a7f1470108cdf65b59 Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Sat, 22 May 2010 17:58:45 +0100 Subject: EXT-7138 WIP Voice Morphing - Go into stateCaptureBufferPaused as soon as the Voice Effects preview is opened. Disconnecting from voice on hitting record was taking too long and causing the start of the voice recording to be cut off. --- indra/newview/llfloatervoiceeffect.cpp | 5 +- indra/newview/llvoiceclient.h | 6 +-- indra/newview/llvoicevivox.cpp | 86 +++++++++++++++------------------- indra/newview/llvoicevivox.h | 13 ++--- 4 files changed, 53 insertions(+), 57 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloatervoiceeffect.cpp b/indra/newview/llfloatervoiceeffect.cpp index 60831936ca..f38a56a06d 100644 --- a/indra/newview/llfloatervoiceeffect.cpp +++ b/indra/newview/llfloatervoiceeffect.cpp @@ -75,6 +75,9 @@ BOOL LLFloaterVoiceEffect::postBuild() if (effect_interface) { effect_interface->addObserver(this); + + // Disconnect from the current voice channel ready to record a voice sample for previewing + effect_interface->enablePreviewBuffer(true); } update(); @@ -88,7 +91,7 @@ void LLFloaterVoiceEffect::onClose(bool app_quitting) LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); if (effect_interface) { - effect_interface->clearPreviewBuffer(); + effect_interface->enablePreviewBuffer(false); } } diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 5caf26c492..2fa309d959 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -306,9 +306,9 @@ public: ////////////////////////////// /// @name Preview buffer //@{ - virtual void recordPreviewBuffer(bool enable) = 0; - virtual void playPreviewBuffer(bool enable, const LLUUID& effect_id = LLUUID::null) = 0; - virtual void clearPreviewBuffer() = 0; + virtual void enablePreviewBuffer(bool enable) = 0; + virtual void recordPreviewBuffer(bool record) = 0; + virtual void playPreviewBuffer(bool play, const LLUUID& effect_id = LLUUID::null) = 0; virtual bool isPreviewRecording() = 0; virtual bool isPreviewReady() = 0; diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 7daf865151..a64c05a3c6 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -342,7 +342,9 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() : mVoiceFontsReceived(false), mVoiceFontsNew(false), + mCaptureBufferMode(false), mCaptureBufferRecording(false), + mCaptureBufferRecorded(false), mCaptureBufferPlaying(false) { mSpeakerVolume = scale_speaker_volume(0); @@ -1130,7 +1132,12 @@ void LLVivoxVoiceClient::stateMachine() //MARK: stateCaptureBufferPaused case stateCaptureBufferPaused: - if (mCaptureBufferRecording) + if (!mCaptureBufferMode) + { + mCaptureBufferRecorded = false; + setState(stateNoChannel); + } + else if (mCaptureBufferRecording) { setState(stateCaptureBufferRecStart); // Update UI, should really be separated from the VoiceFont callback @@ -1141,22 +1148,18 @@ void LLVivoxVoiceClient::stateMachine() setState(stateCaptureBufferPlayStart); notifyVoiceFontObservers(); } - else if (mCaptureBufferClear) - { - mCaptureBufferClear = false; - setState(stateNoChannel); - } break; //MARK: stateCaptureBufferRecStart case stateCaptureBufferRecStart: captureBufferRecordStartSendMessage(); + mCaptureBufferRecorded = true; setState(stateCaptureBufferRecording); break; //MARK: stateCaptureBufferRecording case stateCaptureBufferRecording: - if (!mCaptureBufferRecording || mCaptureBufferPlaying || mCaptureBufferClear) + if (!mCaptureBufferMode || !mCaptureBufferRecording || mCaptureBufferPlaying) { mCaptureBufferRecording = false; captureBufferRecordStopSendMessage(); @@ -1173,7 +1176,7 @@ void LLVivoxVoiceClient::stateMachine() //MARK: stateCaptureBufferPlaying case stateCaptureBufferPlaying: - if (!mCaptureBufferPlaying || mCaptureBufferRecording || mCaptureBufferClear) + if (!mCaptureBufferMode || !mCaptureBufferPlaying || mCaptureBufferRecording) { mCaptureBufferPlaying = false; captureBufferPlayStopSendMessage(); @@ -1382,10 +1385,9 @@ void LLVivoxVoiceClient::stateMachine() mTuningExitState = stateNoChannel; setState(stateMicTuningStart); } - else if(mCaptureBufferRecording) + else if(mCaptureBufferMode) { - mTuningExitState = stateNoChannel; - setState(stateCaptureBufferRecStart); + setState(stateCaptureBufferPaused); } else if(sessionNeedsRelog(mNextAudioSession)) { @@ -6693,42 +6695,43 @@ void LLVivoxVoiceClient::notifyVoiceFontObservers(bool new_fonts) } } -void LLVivoxVoiceClient::recordPreviewBuffer(bool enable) +void LLVivoxVoiceClient::enablePreviewBuffer(bool enable) { - if (enable) - { - mCaptureBufferRecording = true; - LL_DEBUGS("Voice") << "Starting recording" << LL_ENDL; - if(getState() >= stateNoChannel) - { - LL_DEBUGS("Voice") << "no channel" << LL_ENDL; - sessionTerminate(); - } - } - else + mCaptureBufferMode = enable; + if(mCaptureBufferMode && getState() >= stateNoChannel) { - mCaptureBufferRecording = false; + LL_DEBUGS("Voice") << "no channel" << LL_ENDL; + sessionTerminate(); } } -void LLVivoxVoiceClient::playPreviewBuffer(bool enable, const LLUUID& effect_id) +void LLVivoxVoiceClient::recordPreviewBuffer(bool record) { - if (enable && !isPreviewReady()) + if (record && !mCaptureBufferMode) { - LL_DEBUGS("Voice") << "No preview buffer to play" << LL_ENDL; + LL_DEBUGS("Voice") << "Cannot start recording, not in preview mode." << LL_ENDL; return; } - mCaptureBufferPlaying = enable; - if (mCaptureBufferPlaying) - { - mPreviewVoiceFontID = effect_id; - } + mCaptureBufferRecording = record; } -void LLVivoxVoiceClient::clearPreviewBuffer() +void LLVivoxVoiceClient::playPreviewBuffer(bool play, const LLUUID& effect_id) { - mCaptureBufferClear = true; + if (play) + { + if (mCaptureBufferMode && mCaptureBufferRecorded) + { + mPreviewVoiceFontID = effect_id; + } + else + { + LL_DEBUGS("Voice") << "No preview buffer to play." << LL_ENDL; + return; + } + } + + mCaptureBufferPlaying = play; } bool LLVivoxVoiceClient::isPreviewRecording() @@ -6738,18 +6741,8 @@ bool LLVivoxVoiceClient::isPreviewRecording() bool LLVivoxVoiceClient::isPreviewReady() { - state preview_state = getState(); - switch (preview_state) - { - case stateCaptureBufferPaused: - case stateCaptureBufferRecording: - case stateCaptureBufferPlaying: - return true; - break; - default: - return false; - break; - } + return mCaptureBufferRecorded; + } bool LLVivoxVoiceClient::isPreviewPlaying() @@ -6767,7 +6760,6 @@ void LLVivoxVoiceClient::captureBufferRecordStartSendMessage() // Start capture stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.StartBufferCapture.1\">" - << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" << "</Request>" << "\n\n\n"; diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index 5ba8082d56..e4250d2ba3 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -257,9 +257,9 @@ public: ////////////////////////////// /// @name Effect preview buffer //@{ - virtual void recordPreviewBuffer(bool enable); - virtual void playPreviewBuffer(bool enable, const LLUUID& effect_id = LLUUID::null); - virtual void clearPreviewBuffer(); + virtual void enablePreviewBuffer(bool enable); + virtual void recordPreviewBuffer(bool record); + virtual void playPreviewBuffer(bool play, const LLUUID& effect_id = LLUUID::null); virtual bool isPreviewRecording(); virtual bool isPreviewReady(); @@ -919,9 +919,10 @@ private: void captureBufferPlayStartSendMessage(const LLUUID& voice_font_id = LLUUID::null); void captureBufferPlayStopSendMessage(); - bool mCaptureBufferRecording; - bool mCaptureBufferPlaying; - bool mCaptureBufferClear; + bool mCaptureBufferMode; // Disconnected from voice channels while using the capture buffer. + bool mCaptureBufferRecording; // A voice sample is being captured. + bool mCaptureBufferRecorded; // A voice sample is captured in the buffer ready to play. + bool mCaptureBufferPlaying; // A voice sample is being played. LLUUID mPreviewVoiceFontID; }; -- cgit v1.2.3 From 32826f31ebfe19f57a1d8cc7c2f3e81df9b5de74 Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Sat, 22 May 2010 18:09:56 +0100 Subject: EXT-7337 WIP Voice Morphing - Limit maximum recording sample to 15 seconds. --- indra/newview/llvoicevivox.cpp | 8 +++++++- indra/newview/llvoicevivox.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'indra') diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index a64c05a3c6..f1c8ce21d2 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -96,6 +96,9 @@ 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; +// Maximum length of capture buffer recordings +const F32 CAPTURE_BUFFER_MAX_TIME = 15.f; + static int scale_mic_volume(float volume) { @@ -1154,12 +1157,15 @@ void LLVivoxVoiceClient::stateMachine() case stateCaptureBufferRecStart: captureBufferRecordStartSendMessage(); mCaptureBufferRecorded = true; + mCaptureTimer.start(); + mCaptureTimer.setTimerExpirySec(CAPTURE_BUFFER_MAX_TIME); setState(stateCaptureBufferRecording); break; //MARK: stateCaptureBufferRecording case stateCaptureBufferRecording: - if (!mCaptureBufferMode || !mCaptureBufferRecording || mCaptureBufferPlaying) + if (!mCaptureBufferMode || !mCaptureBufferRecording || + mCaptureBufferPlaying || mCaptureTimer.hasExpired()) { mCaptureBufferRecording = false; captureBufferRecordStopSendMessage(); diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index e4250d2ba3..3c7567610d 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -924,6 +924,7 @@ private: bool mCaptureBufferRecorded; // A voice sample is captured in the buffer ready to play. bool mCaptureBufferPlaying; // A voice sample is being played. + LLTimer mCaptureTimer; LLUUID mPreviewVoiceFontID; }; -- cgit v1.2.3 From 1ebbe196910110eb51497f272abde277f8f0f69a Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Sun, 23 May 2010 02:22:48 +0100 Subject: EXT-7337 WIP Voice morph previewing Separate Play and Stop callbacks, to allow single click previews in the effect list. --- indra/newview/llfloatervoiceeffect.cpp | 61 ++++++++--- indra/newview/llfloatervoiceeffect.h | 4 +- indra/newview/llvoiceclient.h | 5 +- indra/newview/llvoicevivox.cpp | 118 +++++++++++++++------ indra/newview/llvoicevivox.h | 9 +- .../skins/default/xui/en/floater_voice_effect.xml | 4 +- 6 files changed, 142 insertions(+), 59 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloatervoiceeffect.cpp b/indra/newview/llfloatervoiceeffect.cpp index f38a56a06d..0fa6135da2 100644 --- a/indra/newview/llfloatervoiceeffect.cpp +++ b/indra/newview/llfloatervoiceeffect.cpp @@ -43,6 +43,7 @@ LLFloaterVoiceEffect::LLFloaterVoiceEffect(const LLSD& key) { mCommitCallbackRegistrar.add("VoiceEffect.Record", boost::bind(&LLFloaterVoiceEffect::onClickRecord, this)); mCommitCallbackRegistrar.add("VoiceEffect.Play", boost::bind(&LLFloaterVoiceEffect::onClickPlay, this)); + mCommitCallbackRegistrar.add("VoiceEffect.Stop", boost::bind(&LLFloaterVoiceEffect::onClickStop, this)); mCommitCallbackRegistrar.add("VoiceEffect.Add", boost::bind(&LLFloaterVoiceEffect::onClickAdd, this)); mCommitCallbackRegistrar.add("VoiceEffect.Activate", boost::bind(&LLFloaterVoiceEffect::onClickActivate, this)); } @@ -68,6 +69,7 @@ BOOL LLFloaterVoiceEffect::postBuild() mVoiceEffectList = getChild<LLScrollListCtrl>("voice_effect_list"); if (mVoiceEffectList) { + mVoiceEffectList->setCommitCallback(boost::bind(&LLFloaterVoiceEffect::onClickPlay, this)); mVoiceEffectList->setDoubleClickCallback(boost::bind(&LLFloaterVoiceEffect::onClickActivate, this)); } @@ -80,7 +82,8 @@ BOOL LLFloaterVoiceEffect::postBuild() effect_interface->enablePreviewBuffer(true); } - update(); + refreshEffectList(); + updateControls(); return TRUE; } @@ -95,7 +98,7 @@ void LLFloaterVoiceEffect::onClose(bool app_quitting) } } -void LLFloaterVoiceEffect::update() +void LLFloaterVoiceEffect::refreshEffectList() { if (!mVoiceEffectList) { @@ -194,23 +197,42 @@ void LLFloaterVoiceEffect::update() mVoiceEffectList->setValue(effect_interface->getVoiceEffect()); mVoiceEffectList->setEnabled(true); +} + +void LLFloaterVoiceEffect::updateControls() +{ + bool recording = false; + bool playing = false; + + LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); + if (effect_interface) + { + recording = effect_interface->isPreviewRecording(); + playing = effect_interface->isPreviewPlaying(); + } - // Update button states - // *TODO: Should separate this from rebuilding the effects list, to avoid rebuilding it unnecessarily - bool recording = effect_interface->isPreviewRecording(); getChild<LLButton>("record_btn")->setVisible(!recording); getChild<LLButton>("record_stop_btn")->setVisible(recording); - getChild<LLButton>("play_btn")->setEnabled(effect_interface->isPreviewReady()); - bool playing = effect_interface->isPreviewPlaying(); getChild<LLButton>("play_btn")->setVisible(!playing); getChild<LLButton>("play_stop_btn")->setVisible(playing); + + getChild<LLButton>("play_btn")->setEnabled(effect_interface->isPreviewReady()); + + if (!mVoiceEffectList) + { + mVoiceEffectList->setValue(effect_interface->getVoiceEffect()); + } } // virtual void LLFloaterVoiceEffect::onVoiceEffectChanged(bool new_effects) { - update(); + if (new_effects) + { + refreshEffectList(); + } + updateControls(); } void LLFloaterVoiceEffect::onClickRecord() @@ -219,11 +241,9 @@ void LLFloaterVoiceEffect::onClickRecord() LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); if (effect_interface) { - bool record = !effect_interface->isPreviewRecording(); - effect_interface->recordPreviewBuffer(record); - getChild<LLButton>("record_btn")->setVisible(!record); - getChild<LLButton>("record_stop_btn")->setVisible(record); + effect_interface->recordPreviewBuffer(); } + updateControls(); } void LLFloaterVoiceEffect::onClickPlay() @@ -239,11 +259,20 @@ void LLFloaterVoiceEffect::onClickPlay() LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); if (effect_interface) { - bool play = !effect_interface->isPreviewPlaying(); - effect_interface->playPreviewBuffer(play, effect_id); - getChild<LLButton>("play_btn")->setVisible(!play); - getChild<LLButton>("play_stop_btn")->setVisible(play); + effect_interface->playPreviewBuffer(effect_id); + } + updateControls(); +} + +void LLFloaterVoiceEffect::onClickStop() +{ + LL_DEBUGS("Voice") << "Stop clicked" << LL_ENDL; + LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); + if (effect_interface) + { + effect_interface->stopPreviewBuffer(); } + updateControls(); } void LLFloaterVoiceEffect::onClickAdd() diff --git a/indra/newview/llfloatervoiceeffect.h b/indra/newview/llfloatervoiceeffect.h index 5ad64f0e26..060ffc99e9 100644 --- a/indra/newview/llfloatervoiceeffect.h +++ b/indra/newview/llfloatervoiceeffect.h @@ -53,13 +53,15 @@ public: virtual void onClose(bool app_quitting); private: - void update(); + void refreshEffectList(); + void updateControls(); /// Called by voice effect provider when voice effect list is changed. virtual void onVoiceEffectChanged(bool new_effects); void onClickRecord(); void onClickPlay(); + void onClickStop(); void onClickAdd(); void onClickActivate(); diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 2fa309d959..02c0ece427 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -307,8 +307,9 @@ public: /// @name Preview buffer //@{ virtual void enablePreviewBuffer(bool enable) = 0; - virtual void recordPreviewBuffer(bool record) = 0; - virtual void playPreviewBuffer(bool play, const LLUUID& effect_id = LLUUID::null) = 0; + virtual void recordPreviewBuffer() = 0; + virtual void playPreviewBuffer(const LLUUID& effect_id = LLUUID::null) = 0; + virtual void stopPreviewBuffer() = 0; virtual bool isPreviewRecording() = 0; virtual bool isPreviewReady() = 0; diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index f1c8ce21d2..ba68795870 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -348,7 +348,8 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() : mCaptureBufferMode(false), mCaptureBufferRecording(false), mCaptureBufferRecorded(false), - mCaptureBufferPlaying(false) + mCaptureBufferPlaying(false), + mPlayRequestCount(0) { mSpeakerVolume = scale_speaker_volume(0); @@ -1137,28 +1138,39 @@ void LLVivoxVoiceClient::stateMachine() case stateCaptureBufferPaused: if (!mCaptureBufferMode) { + // Leaving capture mode. + + mCaptureBufferRecording = false; mCaptureBufferRecorded = false; + mCaptureBufferPlaying = false; + + // Return to stateNoChannel to trigger reconnection to a channel. setState(stateNoChannel); } else if (mCaptureBufferRecording) { setState(stateCaptureBufferRecStart); - // Update UI, should really be separated from the VoiceFont callback - notifyVoiceFontObservers(); } else if (mCaptureBufferPlaying) { setState(stateCaptureBufferPlayStart); - notifyVoiceFontObservers(); } break; //MARK: stateCaptureBufferRecStart case stateCaptureBufferRecStart: captureBufferRecordStartSendMessage(); + + // Flag that something is recorded to allow playback. mCaptureBufferRecorded = true; + + // Start the timer, recording will be stopped when it expires. mCaptureTimer.start(); mCaptureTimer.setTimerExpirySec(CAPTURE_BUFFER_MAX_TIME); + + // Update UI, should really use a separate callback. + notifyVoiceFontObservers(false); + setState(stateCaptureBufferRecording); break; @@ -1167,27 +1179,47 @@ void LLVivoxVoiceClient::stateMachine() if (!mCaptureBufferMode || !mCaptureBufferRecording || mCaptureBufferPlaying || mCaptureTimer.hasExpired()) { - mCaptureBufferRecording = false; + // Stop recording captureBufferRecordStopSendMessage(); + mCaptureBufferRecording = false; + + // Update UI, should really use a separate callback. + notifyVoiceFontObservers(false); + setState(stateCaptureBufferPaused); - notifyVoiceFontObservers(); } break; //MARK: stateCaptureBufferPlayStart case stateCaptureBufferPlayStart: - captureBufferPlayStartSendMessage(mPreviewVoiceFontID); + captureBufferPlayStartSendMessage(mPreviewVoiceFont); + + // Store the voice font being previewed, so that we know to restart if it changes. + mPreviewVoiceFontLast = mPreviewVoiceFont; + + // Update UI, should really use a separate callback. + notifyVoiceFontObservers(false); + setState(stateCaptureBufferPlaying); break; //MARK: stateCaptureBufferPlaying case stateCaptureBufferPlaying: - if (!mCaptureBufferMode || !mCaptureBufferPlaying || mCaptureBufferRecording) + if (mCaptureBufferPlaying && mPreviewVoiceFont != mPreviewVoiceFontLast) { - mCaptureBufferPlaying = false; + // If the preview voice font changes, restart playing with the new font. + setState(stateCaptureBufferPlayStart); + } + else if (!mCaptureBufferMode || !mCaptureBufferPlaying || mCaptureBufferRecording) + { + // Stop playing. captureBufferPlayStopSendMessage(); + mCaptureBufferPlaying = false; + + // Update UI, should really use a separate callback. + notifyVoiceFontObservers(false); + setState(stateCaptureBufferPaused); - notifyVoiceFontObservers(); } break; @@ -1723,7 +1755,7 @@ void LLVivoxVoiceClient::stateMachine() { mAudioSessionChanged = false; notifyParticipantObservers(); - notifyVoiceFontObservers(); + notifyVoiceFontObservers(false); } else if (mAudioSession && mAudioSession->mParticipantsChanged) { @@ -3546,7 +3578,11 @@ void LLVivoxVoiceClient::mediaCompletionEvent(std::string &sessionGroupHandle, s } else if (mediaCompletionType == "AuxBufferAudioRender") { - mCaptureBufferPlaying = false; + // Ignore all but the last stop event + if (--mPlayRequestCount <= 0) + { + mCaptureBufferPlaying = false; + } } else { @@ -6392,7 +6428,7 @@ bool LLVivoxVoiceClient::setVoiceEffect(const LLUUID& id) gSavedPerAccountSettings.setString("VoiceEffectDefault", id.asString()); sessionSetVoiceFontSendMessage(mAudioSession); - notifyVoiceFontObservers(); + notifyVoiceFontObservers(false); return true; } @@ -6669,14 +6705,13 @@ void LLVivoxVoiceClient::accountGetSessionFontsResponse(int statusCode, const st } mVoiceFontsReceived = true; - notifyVoiceFontObservers(mVoiceFontsNew); - mVoiceFontsNew = false; + notifyVoiceFontObservers(true); } void LLVivoxVoiceClient::accountGetTemplateFontsResponse(int statusCode, const std::string &statusString) { // Voice font list entries were updated via addVoiceFont() during parsing. - notifyVoiceFontObservers(); + notifyVoiceFontObservers(true); } void LLVivoxVoiceClient::addObserver(LLVoiceEffectObserver* observer) { @@ -6711,49 +6746,58 @@ void LLVivoxVoiceClient::enablePreviewBuffer(bool enable) } } -void LLVivoxVoiceClient::recordPreviewBuffer(bool record) +void LLVivoxVoiceClient::recordPreviewBuffer() { - if (record && !mCaptureBufferMode) + if (!mCaptureBufferMode) { - LL_DEBUGS("Voice") << "Cannot start recording, not in preview mode." << LL_ENDL; + LL_DEBUGS("Voice") << "Not in voice effect preview mode, cannot start recording." << LL_ENDL; + mCaptureBufferRecording = false; return; } - mCaptureBufferRecording = record; + mCaptureBufferRecording = true; } -void LLVivoxVoiceClient::playPreviewBuffer(bool play, const LLUUID& effect_id) +void LLVivoxVoiceClient::playPreviewBuffer(const LLUUID& effect_id) { - if (play) + if (!mCaptureBufferMode) { - if (mCaptureBufferMode && mCaptureBufferRecorded) - { - mPreviewVoiceFontID = effect_id; - } - else - { - LL_DEBUGS("Voice") << "No preview buffer to play." << LL_ENDL; - return; - } + LL_DEBUGS("Voice") << "Not in voice effect preview mode, no buffer to play." << LL_ENDL; + mCaptureBufferRecording = false; + return; + } + + if (!mCaptureBufferRecorded) + { + // Can't play until we have something recorded! + mCaptureBufferPlaying = false; + return; } - mCaptureBufferPlaying = play; + mPreviewVoiceFont = effect_id; + mCaptureBufferPlaying = true; +} + +void LLVivoxVoiceClient::stopPreviewBuffer() +{ + mCaptureBufferRecording = false; + mCaptureBufferPlaying = false; } bool LLVivoxVoiceClient::isPreviewRecording() { - return mCaptureBufferRecording; + return (mCaptureBufferMode && mCaptureBufferRecording); } bool LLVivoxVoiceClient::isPreviewReady() { - return mCaptureBufferRecorded; + return (mCaptureBufferMode && mCaptureBufferRecorded); } bool LLVivoxVoiceClient::isPreviewPlaying() { - return mCaptureBufferPlaying; + return (mCaptureBufferMode && mCaptureBufferPlaying); } void LLVivoxVoiceClient::captureBufferRecordStartSendMessage() @@ -6811,6 +6855,10 @@ void LLVivoxVoiceClient::captureBufferPlayStartSendMessage(const LLUUID& voice_f { if(!mAccountHandle.empty()) { + // Track how may play requests are sent, so we know how many stop events to + // expect before play actually stops. + ++mPlayRequestCount; + std::ostringstream stream; LL_DEBUGS("Voice") << "Starting audio buffer playback." << LL_ENDL; diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index 3c7567610d..6a13bcddb3 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -258,8 +258,9 @@ public: /// @name Effect preview buffer //@{ virtual void enablePreviewBuffer(bool enable); - virtual void recordPreviewBuffer(bool record); - virtual void playPreviewBuffer(bool play, const LLUUID& effect_id = LLUUID::null); + virtual void recordPreviewBuffer(); + virtual void playPreviewBuffer(const LLUUID& effect_id = LLUUID::null); + virtual void stopPreviewBuffer(); virtual bool isPreviewRecording(); virtual bool isPreviewReady(); @@ -925,7 +926,9 @@ private: bool mCaptureBufferPlaying; // A voice sample is being played. LLTimer mCaptureTimer; - LLUUID mPreviewVoiceFontID; + LLUUID mPreviewVoiceFont; + LLUUID mPreviewVoiceFontLast; + S32 mPlayRequestCount; }; /** 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 d869f6c610..9a6c21c7f2 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_effect.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_effect.xml @@ -153,7 +153,7 @@ top_delta="0" width="135"> <button.commit_callback - function="VoiceEffect.Record" /> + function="VoiceEffect.Stop" /> </button> <button follows="left|bottom" @@ -177,6 +177,6 @@ top_delta="0" width="135"> <button.commit_callback - function="VoiceEffect.Play" /> + function="VoiceEffect.Stop" /> </button> </floater> -- cgit v1.2.3 From 49d8b3f5195e854f8b87fd08098b54eeda51b0ae Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Sun, 23 May 2010 02:31:46 +0100 Subject: EXT-7337 WIP Voice morph previewing - Remove redundant play button now single-click preview is possible. --- indra/newview/skins/default/xui/en/floater_voice_effect.xml | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra') 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 9a6c21c7f2..d0c503f7b8 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_effect.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_effect.xml @@ -155,6 +155,7 @@ <button.commit_callback function="VoiceEffect.Stop" /> </button> +<!-- <button follows="left|bottom" height="23" @@ -179,4 +180,5 @@ <button.commit_callback function="VoiceEffect.Stop" /> </button> +--> </floater> -- cgit v1.2.3 From 6e98ca08300fad1fa8a4a5ab3996e1a6f8318564 Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Sun, 23 May 2010 04:35:31 +0100 Subject: EXT-7337 WIP Voice morph previewing. Remove the activate button in the preview floater for now, it doesn't work in capture mode. Remove the remains of the play button. --- indra/newview/llfloatervoiceeffect.cpp | 45 +++++++-------- indra/newview/llfloatervoiceeffect.h | 2 +- .../skins/default/xui/en/floater_voice_effect.xml | 65 +++------------------- 3 files changed, 30 insertions(+), 82 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloatervoiceeffect.cpp b/indra/newview/llfloatervoiceeffect.cpp index 0fa6135da2..1afea66d91 100644 --- a/indra/newview/llfloatervoiceeffect.cpp +++ b/indra/newview/llfloatervoiceeffect.cpp @@ -45,7 +45,7 @@ LLFloaterVoiceEffect::LLFloaterVoiceEffect(const LLSD& key) mCommitCallbackRegistrar.add("VoiceEffect.Play", boost::bind(&LLFloaterVoiceEffect::onClickPlay, this)); mCommitCallbackRegistrar.add("VoiceEffect.Stop", boost::bind(&LLFloaterVoiceEffect::onClickStop, this)); mCommitCallbackRegistrar.add("VoiceEffect.Add", boost::bind(&LLFloaterVoiceEffect::onClickAdd, this)); - mCommitCallbackRegistrar.add("VoiceEffect.Activate", boost::bind(&LLFloaterVoiceEffect::onClickActivate, this)); +// mCommitCallbackRegistrar.add("VoiceEffect.Activate", boost::bind(&LLFloaterVoiceEffect::onClickActivate, this)); } // virtual @@ -70,7 +70,7 @@ BOOL LLFloaterVoiceEffect::postBuild() if (mVoiceEffectList) { mVoiceEffectList->setCommitCallback(boost::bind(&LLFloaterVoiceEffect::onClickPlay, this)); - mVoiceEffectList->setDoubleClickCallback(boost::bind(&LLFloaterVoiceEffect::onClickActivate, this)); +// mVoiceEffectList->setDoubleClickCallback(boost::bind(&LLFloaterVoiceEffect::onClickActivate, this)); } LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); @@ -133,7 +133,7 @@ void LLFloaterVoiceEffect::refreshEffectList() 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"; + element["columns"][0]["font"]["style"] = "ITALIC"; LLScrollListItem* sl_item = mVoiceEffectList->addElement(element, ADD_BOTTOM); // *HACK: Copied from llfloatergesture.cpp : ["font"]["style"] does not affect font style :( @@ -152,9 +152,16 @@ void LLFloaterVoiceEffect::refreshEffectList() std::string effect_name = it->first; LLSD effect_properties = effect_interface->getVoiceEffectProperties(effect_id); + + // Tag the active effect. + if (effect_id == LLVoiceClient::instance().getVoiceEffectDefault()) + { + effect_name += " " + getString("active_voice_effect"); + } + + std::string expiry_date = effect_properties["expiry_date"].asString(); 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) @@ -168,6 +175,7 @@ void LLFloaterVoiceEffect::refreshEffectList() 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"; @@ -194,8 +202,6 @@ void LLFloaterVoiceEffect::refreshEffectList() mVoiceEffectList->selectByID(*it); } mVoiceEffectList->setScrollPos(scroll_pos); - - mVoiceEffectList->setValue(effect_interface->getVoiceEffect()); mVoiceEffectList->setEnabled(true); } @@ -213,16 +219,6 @@ void LLFloaterVoiceEffect::updateControls() getChild<LLButton>("record_btn")->setVisible(!recording); getChild<LLButton>("record_stop_btn")->setVisible(recording); - - getChild<LLButton>("play_btn")->setVisible(!playing); - getChild<LLButton>("play_stop_btn")->setVisible(playing); - - getChild<LLButton>("play_btn")->setEnabled(effect_interface->isPreviewReady()); - - if (!mVoiceEffectList) - { - mVoiceEffectList->setValue(effect_interface->getVoiceEffect()); - } } // virtual @@ -281,11 +277,12 @@ void LLFloaterVoiceEffect::onClickAdd() LLWeb::loadURL(getString("get_voice_effects_url")); } -void LLFloaterVoiceEffect::onClickActivate() -{ - LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); - if (effect_interface && mVoiceEffectList) - { - effect_interface->setVoiceEffect(mVoiceEffectList->getCurrentID()); - } -} +//void LLFloaterVoiceEffect::onClickActivate() +//{ +// LLVoiceEffectInterface* effect_interface = LLVoiceClient::instance().getVoiceEffectInterface(); +// if (effect_interface && mVoiceEffectList) +// { +// effect_interface->setVoiceEffect(mVoiceEffectList->getCurrentID()); +// } +//} + diff --git a/indra/newview/llfloatervoiceeffect.h b/indra/newview/llfloatervoiceeffect.h index 060ffc99e9..ed38cd6925 100644 --- a/indra/newview/llfloatervoiceeffect.h +++ b/indra/newview/llfloatervoiceeffect.h @@ -63,7 +63,7 @@ private: void onClickPlay(); void onClickStop(); void onClickAdd(); - void onClickActivate(); +// void onClickActivate(); LLUUID mSelectedID; LLScrollListCtrl* mVoiceEffectList; 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 d0c503f7b8..728beece6b 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_effect.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_effect.xml @@ -14,11 +14,14 @@ min_width="240" width="313"> <string name="no_voice_effect"> - No Voice Effect + (No Voice Effect) </string> <string name="get_voice_effects_url"> http://secondlife.com/landing/v0icem0rphingt3st </string> + <string name="active_voice_effect"> + (Active) + </string> <string name="new_voice_effect"> New! </string> @@ -38,8 +41,8 @@ <scroll_list.columns label="New" name="new" - width="48" /> - <scroll_list.columns + width="64" /> + <scroll_list.columns label="Expires" name="expires" width="100" /> @@ -86,6 +89,7 @@ <button.commit_callback function="VoiceEffect.Add" /> </button> +<!-- <button follows="bottom|left" font="SansSerifBigBold" @@ -102,35 +106,8 @@ <button.commit_callback function="VoiceEffect.Activate" /> </button> +--> </panel> -<!-- <panel - background_visible="true" - bevel_style="none" - top_pad="0" - follows="left|right|bottom" - height="30" - label="bottom_panel" - layout="topleft" - left="0" - name="bottom_panel" - width="313"> - <button - follows="bottom|left" - font="SansSerifBigBold" - height="10" - image_hover_selected="Activate_Checkmark" - image_selected="Activate_Checkmark" - image_unselected="Activate_Checkmark" - layout="topleft" - left="10" - name="activate_btn" - tool_tip="Activate/Deactivate selected voice effect" - top="10" - width="10" - <button.commit_callback - function="VoiceEffect.Activate" /> - </button> - </panel> --> <button follows="left|bottom" height="23" @@ -155,30 +132,4 @@ <button.commit_callback function="VoiceEffect.Stop" /> </button> -<!-- - <button - follows="left|bottom" - height="23" - label="Play Preview" - layout="topleft" - left_pad="6" - name="play_btn" - top_delta="0" - width="135"> - <button.commit_callback - function="VoiceEffect.Play" /> - </button> - <button - follows="left|bottom" - height="23" - label="Stop" - layout="topleft" - left_delta="0" - name="play_stop_btn" - top_delta="0" - width="135"> - <button.commit_callback - function="VoiceEffect.Stop" /> - </button> ---> </floater> -- cgit v1.2.3 From 234b3edc26db7cf87a11fc16d9720bf4a9c20177 Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Sun, 23 May 2010 14:11:48 +0100 Subject: EXT-7337 WIP Added explanatory note to the voice morph preview floater --- indra/newview/llfloatervoiceeffect.cpp | 2 ++ .../skins/default/xui/en/floater_voice_effect.xml | 21 +++++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloatervoiceeffect.cpp b/indra/newview/llfloatervoiceeffect.cpp index 1afea66d91..49dd6fa4d9 100644 --- a/indra/newview/llfloatervoiceeffect.cpp +++ b/indra/newview/llfloatervoiceeffect.cpp @@ -65,6 +65,8 @@ LLFloaterVoiceEffect::~LLFloaterVoiceEffect() BOOL LLFloaterVoiceEffect::postBuild() { setDefaultBtn("record_btn"); + getChild<LLButton>("record_btn")->setFocus(true); + mVoiceEffectList = getChild<LLScrollListCtrl>("voice_effect_list"); if (mVoiceEffectList) 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 728beece6b..acd70bce8e 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_effect.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_effect.xml @@ -2,7 +2,7 @@ <floater legacy_header_height="18" can_resize="true" - height="465" + height="415" name="voice_effects" help_topic="voice_effects" title="PREVIEW VOICE MORPHING" @@ -26,12 +26,13 @@ New! </string> <scroll_list - bottom_delta="400" + bottom_delta="300" draw_heading="true" follows="all" layout="topleft" left="0" multi_select="false" + tool_tip="Record a sample of your voice, then click an effect to preview." top="20" name="voice_effect_list"> <scroll_list.columns @@ -108,6 +109,21 @@ </button> --> </panel> + <text + height="40" + word_wrap="true" + use_ellipses="true" + type="string" + text_color="LabelSelectedDisabledColor" + length="1" + follows="left|bottom|right" + layout="topleft" + left="6" + name="status_text" + top_pad="10" + width="300"> + Record a sample of your voice, and then select an effect to preview. Close this window to return to in-world voice. + </text> <button follows="left|bottom" height="23" @@ -115,6 +131,7 @@ layout="topleft" left="6" name="record_btn" + tool_tip="Record a sample of your voice." top_pad="5" width="135"> <button.commit_callback -- cgit v1.2.3 From 1cb14cd52bdd7b795f081043fb4444e0a196f82b Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Sun, 23 May 2010 14:26:24 +0100 Subject: EXT-7337 WIP Removed now redundant isPreviewReady() method. --- indra/newview/llvoiceclient.h | 1 - indra/newview/llvoicevivox.cpp | 6 ------ indra/newview/llvoicevivox.h | 1 - 3 files changed, 8 deletions(-) (limited to 'indra') diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 02c0ece427..7f8f979da0 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -312,7 +312,6 @@ public: virtual void stopPreviewBuffer() = 0; virtual bool isPreviewRecording() = 0; - virtual bool isPreviewReady() = 0; virtual bool isPreviewPlaying() = 0; //@} }; diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index ba68795870..e00b94b421 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -6789,12 +6789,6 @@ bool LLVivoxVoiceClient::isPreviewRecording() return (mCaptureBufferMode && mCaptureBufferRecording); } -bool LLVivoxVoiceClient::isPreviewReady() -{ - return (mCaptureBufferMode && mCaptureBufferRecorded); - -} - bool LLVivoxVoiceClient::isPreviewPlaying() { return (mCaptureBufferMode && mCaptureBufferPlaying); diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index 6a13bcddb3..f67798c207 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -263,7 +263,6 @@ public: virtual void stopPreviewBuffer(); virtual bool isPreviewRecording(); - virtual bool isPreviewReady(); virtual bool isPreviewPlaying(); //@} -- cgit v1.2.3 From 08e610adfa8124fa7b990f952ad3053b955b62d3 Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Sun, 23 May 2010 19:44:30 +0100 Subject: EXT-7335 WIP Parse Vivox voice font expiry timestamps into ISO 8601 standard dates. --- indra/newview/llfloatervoiceeffect.cpp | 10 +++++++-- indra/newview/llvoicevivox.cpp | 40 +++++++++++++++++++++++++++++----- indra/newview/llvoicevivox.h | 8 +++---- 3 files changed, 46 insertions(+), 12 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloatervoiceeffect.cpp b/indra/newview/llfloatervoiceeffect.cpp index 49dd6fa4d9..38c419ab24 100644 --- a/indra/newview/llfloatervoiceeffect.cpp +++ b/indra/newview/llfloatervoiceeffect.cpp @@ -161,7 +161,7 @@ void LLFloaterVoiceEffect::refreshEffectList() effect_name += " " + getString("active_voice_effect"); } - std::string expiry_date = effect_properties["expiry_date"].asString(); + LLDate expiry_date = effect_properties["expiry_date"].asDate(); bool is_template_only = effect_properties["template_only"].asBoolean(); bool is_new = effect_properties["is_new"].asBoolean(); @@ -184,7 +184,13 @@ void LLFloaterVoiceEffect::refreshEffectList() element["columns"][1]["font"]["style"] = font_style; element["columns"][2]["column"] = "expires"; - element["columns"][2]["value"] = !is_template_only ? expiry_date : ""; + if (!is_template_only) + { + element["columns"][2]["value"] = expiry_date; + } + else { + element["columns"][2]["value"] = ""; + } element["columns"][2]["font"]["name"] = "SANSSERIF"; element["columns"][2]["font"]["style"] = font_style; diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index e00b94b421..304321b361 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -6508,7 +6508,7 @@ const voice_effect_list_t& LLVivoxVoiceClient::getVoiceEffectTemplateList() cons void LLVivoxVoiceClient::addVoiceFont(const S32 font_index, const std::string &name, const std::string &description, - const std::string &expiration_date, + const LLDate &expiration_date, const bool has_expired, const S32 font_type, const S32 font_status, @@ -7112,7 +7112,7 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr) id = 0; nameString.clear(); descriptionString.clear(); - expirationDateString.clear(); + expirationDate = LLDate(); hasExpired = false; fontType = 0; fontStatus = 0; @@ -7122,7 +7122,7 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr) id = 0; nameString.clear(); descriptionString.clear(); - expirationDateString.clear(); + expirationDate = LLDate(); hasExpired = false; fontType = 0; fontStatus = 0; @@ -7278,11 +7278,11 @@ void LLVivoxProtocolParser::EndTag(const char *tag) subscriptionType = string; else if (!stricmp("SessionFont", tag)) { - LLVivoxVoiceClient::getInstance()->addVoiceFont(id, nameString, descriptionString, expirationDateString, hasExpired, fontType, fontStatus, false); + LLVivoxVoiceClient::getInstance()->addVoiceFont(id, nameString, descriptionString, expirationDate, hasExpired, fontType, fontStatus, false); } else if (!stricmp("TemplateFont", tag)) { - LLVivoxVoiceClient::getInstance()->addVoiceFont(id, nameString, descriptionString, expirationDateString, hasExpired, fontType, fontStatus, true); + LLVivoxVoiceClient::getInstance()->addVoiceFont(id, nameString, descriptionString, expirationDate, hasExpired, fontType, fontStatus, true); } else if (!stricmp("ID", tag)) { @@ -7294,7 +7294,7 @@ void LLVivoxProtocolParser::EndTag(const char *tag) } else if (!stricmp("ExpirationDate", tag)) { - expirationDateString = string; + expirationDate = vivoxTimeStampToLLDate(string); } else if (!stricmp("Expired", tag)) { @@ -7341,6 +7341,34 @@ void LLVivoxProtocolParser::CharData(const char *buffer, int length) // -------------------------------------------------------------------------------- +LLDate LLVivoxProtocolParser::vivoxTimeStampToLLDate(const std::string& vivox_ts) +{ + // First check to see if it actually already is a proper ISO8601 date, + // in case the format miraculously changes in future ;) + LLDate ts(vivox_ts); + if (ts.notNull()) + { + return ts; + } + + std::string time_stamp = vivox_ts; + + // Vivox's format is missing a T from being standard ISO 8601, + // so add it. It is the only space in their result. + LLStringUtil::replaceChar(time_stamp, ' ', 'T'); + + //also need to remove the hours away from GMT to be compatible + //with LLDate as well as the fractions of seconds + time_stamp = time_stamp.substr(0, time_stamp.length() - 5); + + //it also needs a 'Z' at the end + time_stamp += "Z"; + + return LLDate(time_stamp); +} + +// -------------------------------------------------------------------------------- + void LLVivoxProtocolParser::processResponse(std::string tag) { LL_DEBUGS("VivoxProtocolParser") << tag << LL_ENDL; diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index f67798c207..130fdac146 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -664,7 +664,7 @@ protected: void addVoiceFont(const S32 id, const std::string &name, const std::string &description, - const std::string &expiration_date, + const LLDate &expiration_date, const bool has_expired, const S32 font_type, const S32 font_status, @@ -893,7 +893,7 @@ private: LLUUID mID; S32 mFontIndex; std::string mName; - std::string mExpirationDate; + LLDate mExpirationDate; bool mHasExpired; S32 mFontType; S32 mFontStatus; @@ -1016,7 +1016,7 @@ protected: std::string subscriptionType; S32 id; std::string descriptionString; - std::string expirationDateString; + LLDate expirationDate; bool hasExpired; S32 fontType; S32 fontStatus; @@ -1037,7 +1037,7 @@ protected: void StartTag(const char *tag, const char **attr); void EndTag(const char *tag); void CharData(const char *buffer, int length); - + LLDate vivoxTimeStampToLLDate(const std::string& vivox_ts); }; -- cgit v1.2.3 From 12171ddba3c70b73e53bf103a45779262b38c6ec Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Mon, 24 May 2010 00:20:03 +0100 Subject: EXT-7336 WIP Move the Voice Morphing marketing URL into strings.xml so it can be used in notifications as well. --- indra/newview/llfloatervoiceeffect.cpp | 2 +- indra/newview/llpanelvoiceeffect.cpp | 3 ++- indra/newview/skins/default/xui/en/floater_voice_effect.xml | 3 --- indra/newview/skins/default/xui/en/panel_voice_effect.xml | 3 --- indra/newview/skins/default/xui/en/strings.xml | 10 ++++++---- 5 files changed, 9 insertions(+), 12 deletions(-) (limited to 'indra') diff --git a/indra/newview/llfloatervoiceeffect.cpp b/indra/newview/llfloatervoiceeffect.cpp index 38c419ab24..e30a50fab7 100644 --- a/indra/newview/llfloatervoiceeffect.cpp +++ b/indra/newview/llfloatervoiceeffect.cpp @@ -282,7 +282,7 @@ void LLFloaterVoiceEffect::onClickStop() void LLFloaterVoiceEffect::onClickAdd() { // Open the voice morphing info web page - LLWeb::loadURL(getString("get_voice_effects_url")); + LLWeb::loadURL(LLTrans::getString("voice_morphing_url")); } //void LLFloaterVoiceEffect::onClickActivate() diff --git a/indra/newview/llpanelvoiceeffect.cpp b/indra/newview/llpanelvoiceeffect.cpp index 915d547056..140feb7a54 100644 --- a/indra/newview/llpanelvoiceeffect.cpp +++ b/indra/newview/llpanelvoiceeffect.cpp @@ -38,6 +38,7 @@ #include "llcombobox.h" #include "llfloaterreg.h" #include "llpanel.h" +#include "lltrans.h" #include "llvoiceclient.h" static LLRegisterPanelClassWrapper<LLPanelVoiceEffect> t_panel_voice_effect("panel_voice_effect"); @@ -98,7 +99,7 @@ void LLPanelVoiceEffect::onCommitVoiceEffect() else if (value.asInteger() == GET_VOICE_EFFECTS) { // Open the voice morphing info web page - LLWeb::loadURL(getString("get_voice_effects_url")); + LLWeb::loadURL(LLTrans::getString("voice_morphing_url")); } else { 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 acd70bce8e..7335488e73 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_effect.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_effect.xml @@ -16,9 +16,6 @@ <string name="no_voice_effect"> (No Voice Effect) </string> - <string name="get_voice_effects_url"> - http://secondlife.com/landing/v0icem0rphingt3st - </string> <string name="active_voice_effect"> (Active) </string> diff --git a/indra/newview/skins/default/xui/en/panel_voice_effect.xml b/indra/newview/skins/default/xui/en/panel_voice_effect.xml index 9e5652d1e2..9b6548ef9c 100644 --- a/indra/newview/skins/default/xui/en/panel_voice_effect.xml +++ b/indra/newview/skins/default/xui/en/panel_voice_effect.xml @@ -8,9 +8,6 @@ <string name="no_voice_effect"> No Voice Effect </string> - <string name="get_voice_effects_url"> - http://secondlife.com/landing/v0icem0rphingt3st - </string> <string name="preview_voice_effects"> Preview Voice Morphing ▶ </string> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index f8bb36b88a..a54dd02927 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -3086,10 +3086,12 @@ If you continue to receive this message, contact the [SUPPORT_SITE]. <string name="unread_chat_multiple"> [SOURCES] have said something new </string>" - <string name="session_initialization_timed_out_error"> - The session initialization is timed out - </string> - + <string name="session_initialization_timed_out_error"> + The session initialization is timed out + </string> + + <string name="voice_morphing_url">http://secondlife.com/landing/v0icem0rphingt3st</string> + <!-- Financial operations strings --> <string name="paid_you_ldollars">[NAME] paid you L$[AMOUNT]</string> <string name="you_paid_ldollars">You paid [NAME] L$[AMOUNT] [REASON].</string> -- cgit v1.2.3 From 15c3b2c6309fa4b45376f3d62e33bfcd3ccdbfc7 Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Mon, 24 May 2010 02:27:07 +0100 Subject: EXT-7335 WIP Added notification of expiring voice effects --- indra/newview/app_settings/settings.xml | 11 ++ indra/newview/llfloaternotificationsconsole.cpp | 2 +- indra/newview/llfloatervoiceeffect.cpp | 4 +- indra/newview/llfloatervoiceeffect.h | 2 +- indra/newview/llpanelvoiceeffect.cpp | 2 +- indra/newview/llpanelvoiceeffect.h | 2 +- indra/newview/llvoiceclient.h | 2 +- indra/newview/llvoicevivox.cpp | 187 +++++++++++++++++++-- indra/newview/llvoicevivox.h | 13 +- .../newview/skins/default/xui/en/notifications.xml | 33 ++++ 10 files changed, 232 insertions(+), 26 deletions(-) (limited to 'indra') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index dd5774929e..cb9177587f 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10606,6 +10606,17 @@ <key>Value</key> <integer>1</integer> </map> + <key>VoiceEffectExpiryWarningTime</key> + <map> + <key>Comment</key> + <string>How much notice to give of voice effect subscriptions expiry, in seconds.</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>259200.0</real> + </map> <key>AutoDisengageMic</key> <map> <key>Comment</key> diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp index b744bff084..105d7f9201 100644 --- a/indra/newview/llfloaternotificationsconsole.cpp +++ b/indra/newview/llfloaternotificationsconsole.cpp @@ -184,7 +184,7 @@ BOOL LLFloaterNotificationConsole::postBuild() addChannel("Ignore"); addChannel("Visible", true); // all the ones below attach to the Visible channel - addChannel("History"); + addChannel("Persistent"); addChannel("Alerts"); addChannel("AlertModal"); addChannel("Group Notifications"); diff --git a/indra/newview/llfloatervoiceeffect.cpp b/indra/newview/llfloatervoiceeffect.cpp index e30a50fab7..f31ab96985 100644 --- a/indra/newview/llfloatervoiceeffect.cpp +++ b/indra/newview/llfloatervoiceeffect.cpp @@ -230,9 +230,9 @@ void LLFloaterVoiceEffect::updateControls() } // virtual -void LLFloaterVoiceEffect::onVoiceEffectChanged(bool new_effects) +void LLFloaterVoiceEffect::onVoiceEffectChanged(bool effect_list_updated) { - if (new_effects) + if (effect_list_updated) { refreshEffectList(); } diff --git a/indra/newview/llfloatervoiceeffect.h b/indra/newview/llfloatervoiceeffect.h index ed38cd6925..46b241bd17 100644 --- a/indra/newview/llfloatervoiceeffect.h +++ b/indra/newview/llfloatervoiceeffect.h @@ -57,7 +57,7 @@ private: void updateControls(); /// Called by voice effect provider when voice effect list is changed. - virtual void onVoiceEffectChanged(bool new_effects); + virtual void onVoiceEffectChanged(bool effect_list_updated); void onClickRecord(); void onClickPlay(); diff --git a/indra/newview/llpanelvoiceeffect.cpp b/indra/newview/llpanelvoiceeffect.cpp index 140feb7a54..4f73f38edc 100644 --- a/indra/newview/llpanelvoiceeffect.cpp +++ b/indra/newview/llpanelvoiceeffect.cpp @@ -110,7 +110,7 @@ void LLPanelVoiceEffect::onCommitVoiceEffect() } // virtual -void LLPanelVoiceEffect::onVoiceEffectChanged(bool new_effects) +void LLPanelVoiceEffect::onVoiceEffectChanged(bool effect_list_updated) { update(); } diff --git a/indra/newview/llpanelvoiceeffect.h b/indra/newview/llpanelvoiceeffect.h index 008123a4e4..bd7bdd04f2 100644 --- a/indra/newview/llpanelvoiceeffect.h +++ b/indra/newview/llpanelvoiceeffect.h @@ -56,7 +56,7 @@ private: void update(); /// Called by voice effect provider when voice effect list is changed. - virtual void onVoiceEffectChanged(bool new_effects); + virtual void onVoiceEffectChanged(bool effect_list_updated); // Fixed entries in the voice effect list typedef enum e_voice_effect_combo_items diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 7f8f979da0..744ec84023 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -266,7 +266,7 @@ class LLVoiceEffectObserver { public: virtual ~LLVoiceEffectObserver() { } - virtual void onVoiceEffectChanged(bool new_effects) = 0; + virtual void onVoiceEffectChanged(bool effect_list_updated) = 0; }; typedef std::multimap<const std::string, const LLUUID, LLDictionaryLess> voice_effect_list_t; diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 304321b361..d786b4d928 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -60,6 +60,7 @@ #include "llviewerparcelmgr.h" //#include "llfirstuse.h" #include "llspeakers.h" +#include "lltrans.h" #include "llviewerwindow.h" #include "llviewercamera.h" @@ -96,6 +97,9 @@ 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; +// How often to check for expired voice fonts +const F32 VOICE_FONT_EXPIRY_INTERVAL = 1.f; + // Maximum length of capture buffer recordings const F32 CAPTURE_BUFFER_MAX_TIME = 15.f; @@ -781,7 +785,7 @@ void LLVivoxVoiceClient::stateMachine() closeSocket(); deleteAllSessions(); deleteAllBuddies(); - deleteVoiceFonts(); + deleteAllVoiceFonts(); deleteVoiceFontTemplates(); mConnectorHandle.clear(); @@ -1372,6 +1376,10 @@ void LLVivoxVoiceClient::stateMachine() //MARK: stateVoiceFontsReceived case stateVoiceFontsReceived: // Voice font list received + // Set up the timer to check for expiring voice fonts + mVoiceFontExpiryTimer.start(); + mVoiceFontExpiryTimer.setTimerExpirySec(VOICE_FONT_EXPIRY_INTERVAL); + #if USE_SESSION_GROUPS // create the main session group setState(stateCreatingSessionGroup); @@ -1600,6 +1608,13 @@ void LLVivoxVoiceClient::stateMachine() enforceTether(); } + // Do notifications for expiring Voice Fonts. + if (mVoiceFontExpiryTimer.hasExpired()) + { + expireVoiceFonts(); + mVoiceFontExpiryTimer.setTimerExpirySec(VOICE_FONT_EXPIRY_INTERVAL); + } + // Send an update only if the ptt or mute state has changed (which shouldn't be able to happen that often // -- the user can only click so fast) or every 10hz, whichever is sooner. // Sending for every volume update causes an excessive flood of messages whenever a volume slider is dragged. @@ -1669,7 +1684,7 @@ void LLVivoxVoiceClient::stateMachine() mAccountHandle.clear(); deleteAllSessions(); deleteAllBuddies(); - deleteVoiceFonts(); + deleteAllVoiceFonts(); deleteVoiceFontTemplates(); if(mVoiceEnabled && !mRelogRequested) @@ -6461,7 +6476,6 @@ LLSD LLVivoxVoiceClient::getVoiceEffectProperties(const LLUUID& id) voiceFontEntry *font = iter->second; sd["name"] = font->mName; - sd["expired"] = font->mHasExpired; sd["expiry_date"] = font->mExpirationDate; sd["is_new"] = font->mIsNew; @@ -6471,7 +6485,6 @@ LLSD LLVivoxVoiceClient::getVoiceEffectProperties(const LLUUID& id) LLVivoxVoiceClient::voiceFontEntry::voiceFontEntry(LLUUID& id) : mID(id), mFontIndex(0), - mHasExpired(false), mFontType(VOICE_FONT_TYPE_NONE), mFontStatus(VOICE_FONT_STATUS_NONE), mIsNew(false) @@ -6487,7 +6500,7 @@ void LLVivoxVoiceClient::refreshVoiceEffectLists(bool clear_lists) if (clear_lists) { mVoiceFontsReceived = false; - deleteVoiceFonts(); + deleteAllVoiceFonts(); deleteVoiceFontTemplates(); } @@ -6533,12 +6546,23 @@ void LLVivoxVoiceClient::addVoiceFont(const S32 font_index, voice_font_map_t& font_map = template_font ? mVoiceFontTemplateMap : mVoiceFontMap; voice_effect_list_t& font_list = template_font ? mVoiceFontTemplateList : mVoiceFontList; - // Check whether we've seen this font before and create an entry for it if not. + // Check whether we've seen this font before. voice_font_map_t::iterator iter = font_map.find(font_id); bool new_font = (iter == font_map.end()); + + // If it is a new (unexpired) font create a new entry, otherwise update the existing one. if (new_font) { - font = new voiceFontEntry(font_id); + if (!has_expired) + { + font = new voiceFontEntry(font_id); + } + else + { + LL_DEBUGS("Voice") << (template_font?"Template: ":"") << font_id + << " (" << font_index << ") : " << name << " has expired." << LL_ENDL; + } + } else { @@ -6547,15 +6571,47 @@ void LLVivoxVoiceClient::addVoiceFont(const S32 font_index, if (font) { + // Remove fonts that have expired since we last saw them. + if (has_expired) + { + LL_DEBUGS("Voice") << (template_font?"Template: ":"") << font_id + << " (" << font_index << ") : " << name << " has expired, removing." + << LL_ENDL; + + deleteVoiceFont(font_id); + return; + } + font->mFontIndex = font_index; // Use the description for the human readable name if available, as the // "name" may 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; + F64 expiry_time = 0.f; + + // Set the expiry timer to trigger a notification when the voice font can no longer be used. + font->mExpiryTimer.start(); + expiry_time = expiration_date.secondsSinceEpoch() - LLTimer::getTotalSeconds(); + font->mExpiryTimer.setTimerExpirySec(expiry_time); + + // Set the warning timer to some interval before actual expiry. + F64 warning_time = (F64)gSavedSettings.getF32("VoiceEffectExpiryWarningTime"); + if (warning_time > 0.f) + { + font->mExpiryWarningTimer.start(); + expiry_time = (expiration_date.secondsSinceEpoch() - warning_time) + - LLTimer::getTotalSeconds(); + font->mExpiryWarningTimer.setTimerExpirySec(expiry_time); + } + else + { + // Disable the warning timer. + font->mExpiryWarningTimer.stop(); + } + // Only flag it as a new font if we have already seen the font list. if (!template_font && mVoiceFontsReceived && new_font) { @@ -6563,9 +6619,16 @@ void LLVivoxVoiceClient::addVoiceFont(const S32 font_index, mVoiceFontsNew = true; } + if (new_font) + { + font_map.insert(voice_font_map_t::value_type(font->mID, font)); + font_list.insert(voice_effect_list_t::value_type(font->mName, font->mID)); + } + + // Debugging stuff + LL_DEBUGS("Voice") << (template_font?"Template: ":"") << font_id - << " (" << font_index << ") : " << name << (has_expired?" (Expired)":"") - << LL_ENDL; + << " (" << font_index << ") : " << name << LL_ENDL; if (font_type < VOICE_FONT_TYPE_NONE || font_type >= VOICE_FONT_TYPE_UNKNOWN) { @@ -6575,16 +6638,108 @@ void LLVivoxVoiceClient::addVoiceFont(const S32 font_index, { LL_DEBUGS("Voice") << "Unknown voice font status: " << font_status << LL_ENDL; } + } +} - if (new_font) +void LLVivoxVoiceClient::expireVoiceFonts() +{ + // *TODO: If we are selling voice fonts in packs, there are probably + // going to be a number of fonts with the same expiration time, so would + // be more efficient to just keep a list of expiration times rather + // than checking each font individually. + + bool have_expired = false; + bool will_expire = false; + bool expired_in_use = false; + + LLUUID current_effect = LLVoiceClient::instance().getVoiceEffectDefault(); + + voice_font_map_t::iterator iter; + for (iter = mVoiceFontMap.begin(); iter != mVoiceFontMap.end(); ++iter) + { + voiceFontEntry* voice_font = iter->second; + LLTimer& expiry_timer = voice_font->mExpiryTimer; + LLTimer& warning_timer = voice_font->mExpiryWarningTimer; + + // Check for expired voice fonts + if (expiry_timer.getStarted() && expiry_timer.hasExpired()) { - font_map.insert(voice_font_map_t::value_type(font->mID, font)); - font_list.insert(voice_effect_list_t::value_type(font->mName, font->mID)); + // Check whether it is the active voice font + if (voice_font->mID == current_effect) + { + // Reset to no voice effect. + setVoiceEffect(LLUUID::null); + expired_in_use = true; + } + deleteVoiceFont(voice_font->mID); + have_expired = true; + } + + // Check for voice fonts that will expire in less that the warning time + if (warning_timer.getStarted() && warning_timer.hasExpired()) + { + will_expire = true; + warning_timer.stop(); + } + } + + LLSD args; + args["URL"] = LLTrans::getString("voice_morphing_url"); + + // Give a notification if any voice fonts have expired. + if (have_expired) + { + if (expired_in_use) + { + LLNotificationsUtil::add("VoiceEffectsExpiredInUse", args); + } + else + { + LLNotificationsUtil::add("VoiceEffectsExpired", args); + } + + // Refresh voice font lists in the UI. + notifyVoiceFontObservers(true); + } + + // Give a warning notification if any voice fonts are due to expire. + if (will_expire) + { + S32 seconds = gSavedSettings.getF32("VoiceEffectExpiryWarningTime"); + args["INTERVAL"] = llformat("%d", (seconds / SEC_PER_DAY)); + + LLNotificationsUtil::add("VoiceEffectsWillExpire", args); + } +} + +void LLVivoxVoiceClient::deleteVoiceFont(const LLUUID& id) +{ + // Remove the entry from the voice font list. + voice_effect_list_t::iterator list_iter = mVoiceFontList.begin(); + while (list_iter != mVoiceFontList.end()) + { + if (list_iter->second == id) + { + mVoiceFontList.erase(list_iter++); + } + else + { + ++list_iter; } } + + // Find the entry in the voice font map and erase its data. + voice_font_map_t::iterator map_iter = mVoiceFontMap.find(id); + if (map_iter != mVoiceFontMap.end()) + { + delete map_iter->second; + } + + // Remove the entry from the voice font map. + mVoiceFontMap.erase(map_iter); } -void LLVivoxVoiceClient::deleteVoiceFonts() +void LLVivoxVoiceClient::deleteAllVoiceFonts() { mVoiceFontList.clear(); @@ -6723,14 +6878,14 @@ void LLVivoxVoiceClient::removeObserver(LLVoiceEffectObserver* observer) mVoiceFontObservers.erase(observer); } -void LLVivoxVoiceClient::notifyVoiceFontObservers(bool new_fonts) +void LLVivoxVoiceClient::notifyVoiceFontObservers(bool lists_changed) { for (voice_font_observer_set_t::iterator it = mVoiceFontObservers.begin(); it != mVoiceFontObservers.end(); ) { LLVoiceEffectObserver* observer = *it; - observer->onVoiceEffectChanged(new_fonts); + observer->onVoiceEffectChanged(lists_changed); // In case onVoiceEffectChanged() deleted an entry. it = mVoiceFontObservers.upper_bound(observer); } diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index 130fdac146..d71fe132c5 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -857,7 +857,9 @@ private: // Voice Fonts - void deleteVoiceFonts(); + void expireVoiceFonts(); + void deleteVoiceFont(const LLUUID& id); + void deleteAllVoiceFonts(); void deleteVoiceFontTemplates(); S32 getVoiceFontIndex(const LLUUID& id) const; @@ -867,7 +869,7 @@ private: void accountGetTemplateFontsSendMessage(); void sessionSetVoiceFontSendMessage(sessionState *session); - void notifyVoiceFontObservers(bool new_fonts = false); + void notifyVoiceFontObservers(bool lists_changed = false); typedef enum e_voice_font_type { @@ -894,10 +896,12 @@ private: S32 mFontIndex; std::string mName; LLDate mExpirationDate; - bool mHasExpired; S32 mFontType; S32 mFontStatus; bool mIsNew; + + LLTimer mExpiryTimer; + LLTimer mExpiryWarningTimer; }; bool mVoiceFontsReceived; @@ -912,6 +916,9 @@ private: typedef std::set<LLVoiceEffectObserver*> voice_font_observer_set_t; voice_font_observer_set_t mVoiceFontObservers; + LLTimer mVoiceFontExpiryTimer; + + // Audio capture buffer void captureBufferRecordStartSendMessage(); diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 999f804e71..6b5659f6c0 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -5956,6 +5956,39 @@ We are creating a voice channel for you. This may take up to one minute. <unique/> </notification> + <notification + icon="notify.tga" + name="VoiceEffectsExpired" + sound="UISndAlert" + persist="true" + type="notify"> +Subscribed Voice Effects have expired. +[[URL] Renew your subscription] to reactivate them. + <unique/> + </notification> + + <notification + icon="notify.tga" + name="VoiceEffectsExpiredInUse" + sound="UISndAlert" + persist="true" + type="notify"> +The active Voice Effect has expired, your normal voice settings have been applied. +[[URL] Renew your subscription] to reactivate it. + <unique/> + </notification> + + <notification + icon="notify.tga" + name="VoiceEffectsWillExpire" + sound="UISndAlert" + persist="true" + type="notify"> +Voice Effects will expire in less than [INTERVAL] days. +[[URL] Renew your subscription] or they will be removed. + <unique/> + </notification> + <notification icon="notifytip.tga" name="Cannot enter parcel: not a group member" -- cgit v1.2.3 From 40e240fe61fe8ff989ac906969946d22a186bcf2 Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Mon, 24 May 2010 03:00:29 +0100 Subject: EXT-7138 WIP Renamed VoiceEffectEnabled debug setting to VoiceMorphingEnabled. Hide Me->My Voice menu item when VoiceMorphing is disabled. Removed temporary VoiceFontsAvailable debug setting. --- indra/newview/app_settings/settings.xml | 25 ++++++---------------- indra/newview/llvoiceclient.cpp | 2 +- indra/newview/llvoicevivox.cpp | 3 +-- .../default/xui/en/floater_voice_controls.xml | 2 +- indra/newview/skins/default/xui/en/menu_viewer.xml | 3 ++- 5 files changed, 12 insertions(+), 23 deletions(-) (limited to 'indra') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index cb9177587f..ac289a4fc2 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10584,21 +10584,21 @@ <key>Value</key> <integer>0</integer> </map> - <key>VoiceFontsAvailable</key> + <key>VoiceEffectExpiryWarningTime</key> <map> <key>Comment</key> - <string>Temporary debug setting to test UI with no voice effects available.</string> + <string>How much notice to give of voice effect subscriptions expiry, in seconds.</string> <key>Persist</key> - <integer>0</integer> + <integer>1</integer> <key>Type</key> - <string>Boolean</string> + <string>F32</string> <key>Value</key> - <integer>1</integer> + <real>259200.0</real> </map> - <key>VoiceEffectEnabled</key> + <key>VoiceMorphingEnabled</key> <map> <key>Comment</key> - <string>Whether or not to use Voice Effects and show the UI.</string> + <string>Whether or not to enable Voice Effects and show the UI.</string> <key>Persist</key> <integer>0</integer> <key>Type</key> @@ -10606,17 +10606,6 @@ <key>Value</key> <integer>1</integer> </map> - <key>VoiceEffectExpiryWarningTime</key> - <map> - <key>Comment</key> - <string>How much notice to give of voice effect subscriptions expiry, in seconds.</string> - <key>Persist</key> - <integer>1</integer> - <key>Type</key> - <string>F32</string> - <key>Value</key> - <real>259200.0</real> - </map> <key>AutoDisengageMic</key> <map> <key>Comment</key> diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index d44b47707e..3a51f51c52 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -115,7 +115,7 @@ std::string LLVoiceClientStatusObserver::status2string(LLVoiceClientStatusObserv LLVoiceClient::LLVoiceClient() : mVoiceModule(NULL), - mVoiceEffectEnabled(LLCachedControl<bool>(gSavedSettings, "VoiceEffectEnabled")), + mVoiceEffectEnabled(LLCachedControl<bool>(gSavedSettings, "VoiceMorphingEnabled")), mVoiceEffectDefault(LLCachedControl<std::string>(gSavedPerAccountSettings, "VoiceEffectDefault")) { } diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index d786b4d928..240d7ff164 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -1322,8 +1322,7 @@ void LLVivoxVoiceClient::stateMachine() notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LOGGED_IN); - // *FIX: Remove VoiceFontsAvailable temporary setting (only used to test UI behaviour with no fonts) - if (LLVoiceClient::instance().getVoiceEffectEnabled() && gSavedSettings.getBOOL("VoiceFontsAvailable")) + if (LLVoiceClient::instance().getVoiceEffectEnabled()) { // request the set of available voice fonts setState(stateVoiceFontsWait); 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 216766c3a6..0569b4d515 100644 --- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml +++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml @@ -99,7 +99,7 @@ <panel class="panel_voice_effect" name="panel_voice_effect" - visiblity_control="VoiceEffectEnabled" + visiblity_control="VoiceMorphingEnabled" filename="panel_voice_effect.xml" /> <layout_panel auto_resize="false" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 5425c545e0..96885bf134 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -82,7 +82,8 @@ </menu_item_check> <menu_item_check label="My Voice" - name="ShowVoice"> + name="ShowVoice" + visibility_control="VoiceMorphingEnabled"> <menu_item_check.on_check function="Floater.Visible" parameter="voice_effect" /> -- cgit v1.2.3 From 55c935ea764bc349fa5a329bf190cc6d00f343ca Mon Sep 17 00:00:00 2001 From: Aimee Linden <aimee@lindenlab.com> Date: Mon, 24 May 2010 10:55:41 +0100 Subject: EXT-7335 WIP Changed VoiceEffectExpiryWarningTime from F32 to S32 --- indra/newview/app_settings/settings.xml | 4 ++-- indra/newview/llvoicevivox.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'indra') diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ac289a4fc2..6fa96a653b 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10591,9 +10591,9 @@ <key>Persist</key> <integer>1</integer> <key>Type</key> - <string>F32</string> + <string>S32</string> <key>Value</key> - <real>259200.0</real> + <integer>259200</integer> </map> <key>VoiceMorphingEnabled</key> <map> diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 240d7ff164..c8402af5d1 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -6597,11 +6597,11 @@ void LLVivoxVoiceClient::addVoiceFont(const S32 font_index, font->mExpiryTimer.setTimerExpirySec(expiry_time); // Set the warning timer to some interval before actual expiry. - F64 warning_time = (F64)gSavedSettings.getF32("VoiceEffectExpiryWarningTime"); - if (warning_time > 0.f) + S32 warning_time = gSavedSettings.getS32("VoiceEffectExpiryWarningTime"); + if (warning_time > 0) { font->mExpiryWarningTimer.start(); - expiry_time = (expiration_date.secondsSinceEpoch() - warning_time) + expiry_time = (expiration_date.secondsSinceEpoch() - (F64)warning_time) - LLTimer::getTotalSeconds(); font->mExpiryWarningTimer.setTimerExpirySec(expiry_time); } @@ -6704,8 +6704,8 @@ void LLVivoxVoiceClient::expireVoiceFonts() // Give a warning notification if any voice fonts are due to expire. if (will_expire) { - S32 seconds = gSavedSettings.getF32("VoiceEffectExpiryWarningTime"); - args["INTERVAL"] = llformat("%d", (seconds / SEC_PER_DAY)); + S32 seconds = gSavedSettings.getS32("VoiceEffectExpiryWarningTime"); + args["INTERVAL"] = llformat("%d", seconds / SEC_PER_DAY); LLNotificationsUtil::add("VoiceEffectsWillExpire", args); } -- cgit v1.2.3