Merge branch 'release/webrtc-voice' of https://github.com/secondlife/viewer

# Conflicts:
#	autobuild.xml
#	indra/newview/llspeakers.cpp
#	indra/newview/llvocache.cpp
#	indra/newview/llvoiceclient.cpp
#	indra/newview/skins/default/xui/de/menu_viewer.xml
#	indra/newview/skins/default/xui/en/panel_preferences_sound.xml
#	indra/newview/skins/default/xui/es/menu_viewer.xml
#	indra/newview/skins/default/xui/it/menu_viewer.xml
#	indra/newview/skins/default/xui/ja/menu_viewer.xml
#	indra/newview/skins/default/xui/pl/menu_viewer.xml
#	indra/newview/skins/default/xui/pt/menu_viewer.xml
#	indra/newview/skins/default/xui/ru/menu_viewer.xml
#	indra/newview/skins/default/xui/tr/menu_viewer.xml
#	indra/newview/skins/default/xui/zh/menu_viewer.xml
meow-7.2.2
Ansariel 2024-07-18 20:27:40 +02:00
commit f04ed0e5e4
27 changed files with 160 additions and 205 deletions

View File

@ -880,12 +880,6 @@
<string>https://github.com/secondlife/3p-emoji-shortcodes</string>
<key>description</key>
<string>Emoji shortcodes</string>
<key>name</key>
<string>emoji_shortcodes</string>
<key>canonical_repo</key>
<string>https://github.com/secondlife/3p-emoji-shortcodes</string>
<key>description</key>
<string>Emoji shortcodes</string>
</map>
<key>expat</key>
<map>
@ -2844,7 +2838,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>hash</key>
<string>9ab29796dc144431a9db46fddfbd88b0</string>
<key>hash_algorithm</key>
<string>md5</string>
<string>sha1</string>
<key>url</key>
<string>https://3p.firestormviewer.org/tracy-v0.10.241831929-linux-241831929.tar.bz2</string>
</map>
@ -3242,11 +3236,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>21e31d2c2fffdb59d8f50b80db079f86f2df2483</string>
<string>0a0a972036f2b2c9c97dead40c91f7443b8ab339</string>
<key>hash_algorithm</key>
<string>md5</string>
<string>sha1</string>
<key>url</key>
<string>https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.58/webrtc-m114.5735.08.58.8716173807-darwin64-8716173807.tar.zst</string>
<string>https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.61-debug/webrtc-m114.5735.08.61-debug.9571929057-darwin64-9571929057.tar.zst</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -3256,11 +3250,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>600cabb49a889db3a29f2910f5bda08f28dd04c8</string>
<string>8725ad23f33d946bd5a4e5f28e8c8324925c71a7</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
<string>https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.58/webrtc-m114.5735.08.58.8716173807-linux64-8716173807.tar.zst</string>
<string>https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.61-debug/webrtc-m114.5735.08.61-debug.9571929057-linux64-9571929057.tar.zst</string>
</map>
<key>name</key>
<string>linux64</string>
@ -3270,11 +3264,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>915c9face95efcc6da240aa2c4f8e6c4aa803af8</string>
<string>db560661807db276a3c7d1e7d9531198c9268f68</string>
<key>hash_algorithm</key>
<string>sha1</string>
<key>url</key>
<string>https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.58/webrtc-m114.5735.08.58.8716173807-windows64-8716173807.tar.zst</string>
<string>https://github.com/secondlife/3p-webrtc-build/releases/download/m114.5735.08.61-debug/webrtc-m114.5735.08.61-debug.9571929057-windows64-9571929057.tar.zst</string>
</map>
<key>name</key>
<string>windows64</string>
@ -3287,7 +3281,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>copyright</key>
<string>Copyright (c) 2011, The WebRTC project authors. All rights reserved.</string>
<key>version</key>
<string>m114.5735.08.59-debug.8823062977</string>
<string>m114.5735.08.61-debug.9571929057</string>
<key>name</key>
<string>webrtc</string>
<key>vcs_branch</key>

View File

@ -35,6 +35,7 @@
#include "api/media_stream_interface.h"
#include "api/media_stream_track.h"
#include "modules/audio_processing/audio_buffer.h"
#include "modules/audio_mixer/audio_mixer_impl.h"
namespace llwebrtc
{
@ -88,7 +89,7 @@ void LLAudioDeviceObserver::OnRenderData(const void *audio_samples,
{
}
LLCustomProcessor::LLCustomProcessor() : mSampleRateHz(0), mNumChannels(0), mMicrophoneEnergy(0.0)
LLCustomProcessor::LLCustomProcessor() : mSampleRateHz(0), mNumChannels(0), mMicrophoneEnergy(0.0), mGain(1.0)
{
memset(mSumVector, 0, sizeof(mSumVector));
}
@ -128,9 +129,13 @@ void LLCustomProcessor::Process(webrtc::AudioBuffer *audio_in)
for (size_t index = 0; index < stream_config.num_samples(); index++)
{
float sample = frame_samples[index];
sample = sample * mGain; // apply gain
frame_samples[index] = sample; // write processed sample back to buffer.
energy += sample * sample;
}
audio_in->CopyFrom(&frame[0], stream_config);
// smooth it.
size_t buffer_size = sizeof(mSumVector) / sizeof(mSumVector[0]);
float totalSum = 0;
@ -236,9 +241,9 @@ void LLWebRTCImpl::init()
webrtc::AudioProcessing::Config apm_config;
apm_config.echo_canceller.enabled = false;
apm_config.echo_canceller.mobile_mode = false;
apm_config.gain_controller1.enabled = true;
apm_config.gain_controller1.enabled = false;
apm_config.gain_controller1.mode = webrtc::AudioProcessing::Config::GainController1::kAdaptiveAnalog;
apm_config.gain_controller2.enabled = true;
apm_config.gain_controller2.enabled = false;
apm_config.high_pass_filter.enabled = true;
apm_config.noise_suppression.enabled = true;
apm_config.noise_suppression.level = webrtc::AudioProcessing::Config::NoiseSuppression::kVeryHigh;
@ -260,6 +265,7 @@ void LLWebRTCImpl::init()
mAudioProcessingModule->ApplyConfig(apm_config);
mAudioProcessingModule->Initialize(processing_config);
mPeerConnectionFactory = webrtc::CreatePeerConnectionFactory(mNetworkThread.get(),
mWorkerThread.get(),
mSignalingThread.get(),
@ -336,9 +342,9 @@ void LLWebRTCImpl::setAudioConfig(LLWebRTCDeviceInterface::AudioConfig config)
webrtc::AudioProcessing::Config apm_config;
apm_config.echo_canceller.enabled = config.mEchoCancellation;
apm_config.echo_canceller.mobile_mode = false;
apm_config.gain_controller1.enabled = true;
apm_config.gain_controller1.enabled = config.mAGC;
apm_config.gain_controller1.mode = webrtc::AudioProcessing::Config::GainController1::kAdaptiveAnalog;
apm_config.gain_controller2.enabled = true;
apm_config.gain_controller2.enabled = false;
apm_config.high_pass_filter.enabled = true;
apm_config.transient_suppression.enabled = true;
apm_config.pipeline.multi_channel_render = true;
@ -612,6 +618,8 @@ float LLWebRTCImpl::getTuningAudioLevel() { return -20 * log10f(mTuningAudioDevi
float LLWebRTCImpl::getPeerConnectionAudioLevel() { return -20 * log10f(mPeerCustomProcessor->getMicrophoneEnergy()); }
void LLWebRTCImpl::setPeerConnectionGain(float gain) { mPeerCustomProcessor->setGain(gain); }
//
// Peer Connection Helpers
@ -937,7 +945,7 @@ void LLWebRTCPeerConnectionImpl::setSendVolume(float volume)
{
for (auto &track : mLocalStream->GetAudioTracks())
{
track->GetSource()->SetVolume(volume);
track->GetSource()->SetVolume(volume*5.0);
}
}
});

View File

@ -145,6 +145,7 @@ class LLWebRTCDeviceInterface
virtual void setTuningMode(bool enable) = 0;
virtual float getTuningAudioLevel() = 0; // for use during tuning
virtual float getPeerConnectionAudioLevel() = 0; // for use when not tuning
virtual void setPeerConnectionGain(float gain) = 0;
};
// LLWebRTCAudioInterface provides the viewer with a way

View File

@ -121,6 +121,8 @@ class LLCustomProcessor : public webrtc::CustomProcessing
float getMicrophoneEnergy() { return mMicrophoneEnergy; }
void setGain(float gain) { mGain = gain; }
protected:
static const int NUM_PACKETS_TO_FILTER = 30; // 300 ms of smoothing
int mSampleRateHz;
@ -128,6 +130,7 @@ class LLCustomProcessor : public webrtc::CustomProcessing
float mSumVector[NUM_PACKETS_TO_FILTER];
float mMicrophoneEnergy;
float mGain;
};
@ -160,6 +163,8 @@ class LLWebRTCImpl : public LLWebRTCDeviceInterface, public webrtc::AudioDeviceS
float getTuningAudioLevel() override;
float getPeerConnectionAudioLevel() override;
void setPeerConnectionGain(float gain) override;
//
// AudioDeviceSink
//

View File

@ -359,22 +359,20 @@ void LLConversationItemSession::clearParticipants()
void LLConversationItemSession::clearAndDeparentModels()
{
std::for_each(mChildren.begin(), mChildren.end(),
[](LLFolderViewModelItem* c)
for (LLFolderViewModelItem* child : mChildren)
{
if (child->getNumRefs() == 0)
{
if (c->getNumRefs() == 0)
{
// LLConversationItemParticipant can be created but not assigned to any view,
// it was waiting for an "add_participant" event to be processed
delete c;
}
else
{
// Model is still assigned to some view/widget
c->setParent(NULL);
}
// LLConversationItemParticipant can be created but not assigned to any view,
// it was waiting for an "add_participant" event to be processed
delete child;
}
);
else
{
// Model is still assigned to some view/widget
child->setParent(NULL);
}
}
mChildren.clear();
}

View File

@ -104,6 +104,26 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
LLFloaterIMSessionTab::~LLFloaterIMSessionTab()
{
delete mRefreshTimer;
LLFloaterIMContainer* im_container = LLFloaterIMContainer::findInstance();
if (im_container)
{
LLParticipantList* session = dynamic_cast<LLParticipantList*>(im_container->getSessionModel(mSessionID));
if (session)
{
for (const conversations_widgets_map::value_type& widget_pair : mConversationsWidgets)
{
LLFolderViewItem* widget = widget_pair.second;
LLFolderViewModelItem* item_vmi = widget->getViewModelItem();
if (item_vmi && item_vmi->getNumRefs() == 1)
{
// This is the last pointer, remove participant from session
// before participant gets deleted on destroyView.
session->removeChild(item_vmi);
}
}
}
}
}
// static
@ -665,6 +685,27 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part
LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
if (widget)
{
LLFolderViewModelItem* item_vmi = widget->getViewModelItem();
if (item_vmi && item_vmi->getNumRefs() == 1)
{
// This is the last pointer, remove participant from session
// before participant gets deleted on destroyView.
//
// Floater (widget) and participant's view can simultaneously
// co-own the model, in which case view is responsible for
// the deletion and floater is free to clear and recreate
// the list, yet there are cases where only widget owns
// the pointer so it should do the cleanup.
// See "add_participant".
//
// Todo: If it keeps causing issues turn participants
// into LLPointers in the session
LLParticipantList* session = getParticipantList();
if (session)
{
session->removeChild(item_vmi);
}
}
widget->destroyView();
}
mConversationsWidgets.erase(participant_id);

View File

@ -3906,11 +3906,11 @@ LLUUID LLIMMgr::addSession(
((IM_NOTHING_SPECIAL == dialog) || (IM_SESSION_P2P_INVITE == dialog) || (IM_SESSION_CONFERENCE_START == dialog)) &&
ids.size())
{
LLIMModel::LLIMSession* ad_hoc_found = LLIMModel::getInstance()->findAdHocIMSession(ids);
if (ad_hoc_found)
session = LLIMModel::getInstance()->findAdHocIMSession(ids);
if (session)
{
new_session = false;
session_id = ad_hoc_found->mSessionID;
session_id = session->mSessionID;
}
}
@ -4418,7 +4418,7 @@ bool LLIMMgr::startCall(const LLUUID& session_id, LLVoiceChannel::EDirection dir
{
LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(session_id);
if (!voice_channel) return false;
if (!voice_channel_info.isUndefined())
if (voice_channel_info.isDefined() && voice_channel_info.isMap() && voice_channel_info.size() > 0)
{
voice_channel->setChannelInfo(voice_channel_info);
}

View File

@ -294,6 +294,10 @@ LLSpeakerMgr::~LLSpeakerMgr()
LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::string& name, LLSpeaker::ESpeakerStatus status, LLSpeaker::ESpeakerType type)
{
if (!mVoiceChannel)
{
return NULL;
}
LLUUID session_id = getSessionID();
if (id.isNull() || (id == session_id))
{
@ -496,7 +500,7 @@ void LLSpeakerMgr::updateSpeakerList()
(LLVoiceClient::getInstance()->isParticipantAvatar(*participant_it)?LLSpeaker::SPEAKER_AGENT:LLSpeaker::SPEAKER_EXTERNAL));
}
}
else
else if (mVoiceChannel)
{
// If not, check if the list is empty, except if it's Nearby Chat (session_id NULL).
LLUUID session_id = getSessionID();
@ -827,7 +831,8 @@ void LLIMSpeakerMgr::allowTextChat(const LLUUID& speaker_id, bool allow)
// is unreliable and this leads to situations where people can't be
// chat muted at all anymore
// LLPointer<LLSpeaker> speakerp = findSpeaker(speaker_id);
// if (!speakerp) return;
// if (!speakerp || !mVoiceChannel) return;
if (!mVoiceChannel) return;
std::string url = gAgent.getRegionCapability("ChatSessionRequest");
LLSD data;
@ -848,7 +853,7 @@ void LLIMSpeakerMgr::allowTextChat(const LLUUID& speaker_id, bool allow)
void LLIMSpeakerMgr::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute)
{
LLPointer<LLSpeaker> speakerp = findSpeaker(avatar_id);
if (!speakerp) return;
if (!speakerp || !mVoiceChannel) return;
// *NOTE: mantipov: probably this condition will be incorrect when avatar will be blocked for
// text chat via moderation (LLSpeaker::mModeratorMutedText == TRUE)

View File

@ -11892,15 +11892,6 @@ class LLUpdateMembershipLabel : public view_listener_t
}
};
void handle_voice_morphing_subscribe()
{
LLWeb::loadURL(LLTrans::getString("voice_morphing_url"));
}
void handle_premium_voice_morphing_subscribe()
{
LLWeb::loadURL(LLTrans::getString("premium_voice_morphing_url"));
}
class LLToggleUIHints : public view_listener_t
{
@ -12323,16 +12314,6 @@ void initialize_menus()
// <FS:Ansariel> [FS Communication UI]
//view_listener_t::addMenu(new LLCommunicateNearbyChat(), "Communicate.NearbyChat");
// Communicate > Voice morphing > Subscribe...
commit.add("Communicate.VoiceMorphing.Subscribe", boost::bind(&handle_voice_morphing_subscribe));
// Communicate > Voice morphing > Premium perk...
commit.add("Communicate.VoiceMorphing.PremiumPerk", boost::bind(&handle_premium_voice_morphing_subscribe));
LLVivoxVoiceClient * voice_clientp = LLVivoxVoiceClient::getInstance();
enable.add("Communicate.VoiceMorphing.NoVoiceMorphing.Check"
, boost::bind(&LLVivoxVoiceClient::onCheckVoiceEffect, voice_clientp, "NoVoiceMorphing"));
commit.add("Communicate.VoiceMorphing.NoVoiceMorphing.Click"
, boost::bind(&LLVivoxVoiceClient::onClickVoiceEffect, voice_clientp, "NoVoiceMorphing"));
// World menu
view_listener_t::addMenu(new LLWorldAlwaysRun(), "World.AlwaysRun");
view_listener_t::addMenu(new LLWorldCreateLandmark(), "World.CreateLandmark");

View File

@ -96,7 +96,7 @@ void LLVoiceChannel::setChannelInfo(const LLSD &channelInfo)
if (mState == STATE_NO_CHANNEL_INFO)
{
if (mChannelInfo.isUndefined())
if (mChannelInfo.isUndefined() || !mChannelInfo.isMap() || mChannelInfo.size() == 0)
{
LLNotificationsUtil::add("VoiceChannelJoinFailed", mNotifyArgs);
LL_WARNS("Voice") << "Received empty channel info for channel " << mSessionName << LL_ENDL;
@ -122,7 +122,7 @@ void LLVoiceChannel::onChange(EStatusType type, const LLSD& channelInfo, bool pr
{
LL_DEBUGS("Voice") << "Incoming channel info: " << channelInfo << LL_ENDL;
LL_DEBUGS("Voice") << "Current channel info: " << mChannelInfo << LL_ENDL;
if (mChannelInfo.isUndefined())
if (mChannelInfo.isUndefined() || (mChannelInfo.isMap() && mChannelInfo.size() == 0))
{
mChannelInfo = channelInfo;
}
@ -477,7 +477,7 @@ void LLVoiceChannelGroup::setChannelInfo(const LLSD& channelInfo)
if (mState == STATE_NO_CHANNEL_INFO)
{
if(!mChannelInfo.isUndefined())
if(mChannelInfo.isDefined() && mChannelInfo.isMap())
{
setState(STATE_READY);
@ -676,9 +676,9 @@ void LLVoiceChannelProximal::activate()
// we're connected to a non-spatial channel, so disconnect.
LLVoiceClient::getInstance()->leaveNonSpatialChannel();
}
LLVoiceClient::getInstance()->activateSpatialChannel(true);
LLVoiceChannel::activate();
}
void LLVoiceChannelProximal::onChange(EStatusType type, const LLSD& channelInfo, bool proximal)
@ -751,7 +751,7 @@ void LLVoiceChannelProximal::deactivate()
{
setState(STATE_HUNG_UP);
}
LLVoiceClient::getInstance()->removeObserver(this);
LLVoiceClient::getInstance()->activateSpatialChannel(false);
}
@ -907,7 +907,7 @@ void LLVoiceChannelP2P::setChannelInfo(const LLSD& channel_info)
}
mReceivedCall = TRUE;
if (!channel_info.isUndefined())
if (channel_info.isDefined() && channel_info.isMap())
{
mIncomingCallInterface = LLVoiceClient::getInstance()->getIncomingCallInterface(channel_info);
}

View File

@ -147,6 +147,7 @@ LLVoiceClient::LLVoiceClient(LLPumpIO *pump)
m_servicePump(NULL),
mVoiceEffectEnabled(LLCachedControl<bool>(gSavedSettings, "VoiceMorphingEnabled", true)),
mVoiceEffectDefault(LLCachedControl<std::string>(gSavedPerAccountSettings, "VoiceEffectDefault", "00000000-0000-0000-0000-000000000000")),
mVoiceEffectSupportNotified(false),
mPTTDirty(true),
mPTT(true),
mUsePTT(true),
@ -582,6 +583,26 @@ void LLVoiceClient::setMicGain(F32 gain)
//------------------------------------------
// enable/disable voice features
// static
bool LLVoiceClient::onVoiceEffectsNotSupported(const LLSD &notification, const LLSD &response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
switch (option)
{
case 0: // "Okay"
gSavedPerAccountSettings.setString("VoiceEffectDefault", LLUUID::null.asString());
break;
case 1: // "Cancel"
break;
default:
llassert(0);
break;
}
return false;
}
// <FS:Ansariel> Bypass LLCachedControls for voice status update
//bool LLVoiceClient::voiceEnabled()
bool LLVoiceClient::voiceEnabled(bool no_cache)
@ -594,7 +615,13 @@ bool LLVoiceClient::voiceEnabled(bool no_cache)
static LLCachedControl<bool> enable_voice_chat(gSavedSettings, "EnableVoiceChat");
static LLCachedControl<bool> cmd_line_disable_voice(gSavedSettings, "CmdLineDisableVoice");
return enable_voice_chat && !cmd_line_disable_voice && !gNonInteractive;
bool enabled = enable_voice_chat && !cmd_line_disable_voice && !gNonInteractive;
if (enabled && !mVoiceEffectSupportNotified && getVoiceEffectEnabled() && !getVoiceEffectDefault().isNull())
{
LLNotificationsUtil::add("VoiceEffectsNotSupported", LLSD(), LLSD(), &LLVoiceClient::onVoiceEffectsNotSupported);
mVoiceEffectSupportNotified = true;
}
return enabled;
}
void LLVoiceClient::setVoiceEnabled(bool enabled)
@ -875,7 +902,7 @@ std::string LLVoiceClient::sipURIFromID(const LLUUID &id)
LLVoiceEffectInterface* LLVoiceClient::getVoiceEffectInterface() const
{
return getVoiceEffectEnabled() ? dynamic_cast<LLVoiceEffectInterface*>(mSpatialVoiceModule) : NULL;
return NULL;
}
///////////////////

View File

@ -539,6 +539,8 @@ public:
protected:
static bool onVoiceEffectsNotSupported(const LLSD &notification, const LLSD &response);
LLVoiceModuleInterface* mSpatialVoiceModule;
LLVoiceModuleInterface* mNonSpatialVoiceModule;
LLSD mSpatialCredentials; // used to store spatial credentials for vivox
@ -550,6 +552,7 @@ protected:
LLCachedControl<bool> mVoiceEffectEnabled;
LLCachedControl<std::string> mVoiceEffectDefault;
bool mVoiceEffectSupportNotified;
bool mPTTDirty;
bool mPTT;

View File

@ -2646,7 +2646,6 @@ void LLVivoxVoiceClient::sessionCreateSendMessage(const sessionStatePtr_t &sessi
stream
<< "<ConnectAudio>" << (startAudio?"true":"false") << "</ConnectAudio>"
<< "<ConnectText>" << (startText?"true":"false") << "</ConnectText>"
<< "<VoiceFontID>" << font_index << "</VoiceFontID>"
<< "<Name>" << mChannelName << "</Name>"
<< "</Request>\n\n\n";
LL_WARNS("Voice") << "Session.Create: " << stream.str() << LL_ENDL;
@ -2685,7 +2684,6 @@ void LLVivoxVoiceClient::sessionGroupAddSessionSendMessage(const sessionStatePtr
<< "<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"
@ -2709,7 +2707,6 @@ void LLVivoxVoiceClient::sessionMediaConnectSendMessage(const sessionStatePtr_t
<< "<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";
@ -5247,25 +5244,31 @@ void LLVivoxVoiceClient::processChannels(bool process)
bool LLVivoxVoiceClient::isCurrentChannel(const LLSD &channelInfo)
{
if (!mProcessChannels || (channelInfo["voice_server_type"].asString() != VIVOX_VOICE_SERVER_TYPE))
if (!mProcessChannels || (channelInfo.has("voice_server_type") && channelInfo["voice_server_type"].asString() != VIVOX_VOICE_SERVER_TYPE))
{
return false;
}
if (mAudioSession)
// favor the next audio session, as that's the one we're bringing up.
sessionStatePtr_t session = mNextAudioSession;
if (!session)
{
session = mAudioSession;
}
if (session)
{
if (!channelInfo["session_handle"].asString().empty())
{
return mAudioSession->mHandle == channelInfo["session_handle"].asString();
return session->mHandle == channelInfo["session_handle"].asString();
}
return channelInfo["channel_uri"].asString() == mAudioSession->mSIPURI;
return channelInfo["channel_uri"].asString() == session->mSIPURI;
}
return false;
}
bool LLVivoxVoiceClient::compareChannels(const LLSD& channelInfo1, const LLSD& channelInfo2)
{
return (channelInfo1["voice_server_type"] == VIVOX_VOICE_SERVER_TYPE) &&
(channelInfo1["voice_server_type"] == channelInfo2["voice_server_type"]) &&
return (!channelInfo1.has("voice_server_type") || (channelInfo1["voice_server_type"] == VIVOX_VOICE_SERVER_TYPE)) &&
(!channelInfo2.has("voice_server_type") || (channelInfo2["voice_server_type"] == VIVOX_VOICE_SERVER_TYPE)) &&
(channelInfo1["channel_uri"] == channelInfo2["channel_uri"]);
}

View File

@ -87,7 +87,7 @@ namespace {
const F32 VOLUME_SCALE_WEBRTC = 0.01f;
const F32 LEVEL_SCALE_WEBRTC = 0.008f;
const F32 SPEAKING_AUDIO_LEVEL = 0.35;
const F32 SPEAKING_AUDIO_LEVEL = 0.30;
static const std::string REPORTED_VOICE_SERVER_TYPE = "Secondlife WebRTC Gateway";
@ -1484,14 +1484,10 @@ void LLWebRTCVoiceClient::setMicGain(F32 gain)
if (gain != mMicGain)
{
mMicGain = gain;
sessionState::for_each(boost::bind(predSetMicGain, _1, gain));
mWebRTCDeviceInterface->setPeerConnectionGain(gain);
}
}
void LLWebRTCVoiceClient::predSetMicGain(const LLWebRTCVoiceClient::sessionStatePtr_t &session, F32 gain)
{
session->setMicGain(gain);
}
void LLWebRTCVoiceClient::setVoiceEnabled(bool enabled)
{
@ -1690,7 +1686,6 @@ std::map<std::string, LLWebRTCVoiceClient::sessionState::ptr_t> LLWebRTCVoiceCli
LLWebRTCVoiceClient::sessionState::sessionState() :
mHangupOnLastLeave(false),
mNotifyOnFirstJoin(false),
mMicGain(1.0),
mMuted(false),
mSpeakerVolume(1.0),
mShuttingDown(false)
@ -1735,15 +1730,6 @@ void LLWebRTCVoiceClient::sessionState::setMuteMic(bool muted)
}
}
void LLWebRTCVoiceClient::sessionState::setMicGain(F32 gain)
{
mMicGain = gain;
for (auto &connection : mWebRTCConnections)
{
connection->setMicGain(gain);
}
}
void LLWebRTCVoiceClient::sessionState::setSpeakerVolume(F32 volume)
{
mSpeakerVolume = volume;
@ -1848,7 +1834,6 @@ LLWebRTCVoiceClient::sessionStatePtr_t LLWebRTCVoiceClient::addSession(const std
LL_DEBUGS("Voice") << "adding new session with channel: " << channel_id << LL_ENDL;
session->setMuteMic(mMuteMic);
session->setMicGain(mMicGain);
session->setSpeakerVolume(mSpeakerVolume);
sessionState::addSession(channel_id, session);
@ -1974,7 +1959,6 @@ bool LLWebRTCVoiceClient::estateSessionState::processConnectionStates()
connectionPtr_t connection(new LLVoiceWebRTCSpatialConnection(neighbor, INVALID_PARCEL_ID, mChannelID));
mWebRTCConnections.push_back(connection);
connection->setMicGain(mMicGain);
connection->setMuteMic(mMuted);
connection->setSpeakerVolume(mSpeakerVolume);
}
@ -2104,7 +2088,6 @@ LLVoiceWebRTCConnection::LLVoiceWebRTCConnection(const LLUUID &regionID, const s
mShutDown(false),
mIceCompleted(false),
mSpeakerVolume(0.0),
mMicGain(0.0),
mOutstandingRequests(0),
mChannelID(channelID),
mRegionID(regionID),
@ -2367,15 +2350,6 @@ void LLVoiceWebRTCConnection::setMuteMic(bool muted)
}
}
void LLVoiceWebRTCConnection::setMicGain(F32 gain)
{
mMicGain = gain;
if (mWebRTCAudioInterface)
{
mWebRTCAudioInterface->setSendVolume(gain);
}
}
void LLVoiceWebRTCConnection::setSpeakerVolume(F32 volume)
{
mSpeakerVolume = volume;
@ -2685,7 +2659,6 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
// this connection.
mWebRTCAudioInterface->setMute(mMuted);
mWebRTCAudioInterface->setReceiveVolume(mSpeakerVolume);
mWebRTCAudioInterface->setSendVolume(mMicGain);
LLWebRTCVoiceClient::getInstance()->OnConnectionEstablished(mChannelID, mRegionID);
setVoiceConnectionState(VOICE_STATE_WAIT_FOR_DATA_CHANNEL);
break;

View File

@ -282,7 +282,6 @@ public:
virtual void sendData(const std::string &data);
void setMuteMic(bool muted);
void setMicGain(F32 volume);
void setSpeakerVolume(F32 volume);
void setUserVolume(const LLUUID& id, F32 volume);
@ -303,7 +302,6 @@ public:
std::string mName;
bool mMuted; // this session is muted.
F32 mMicGain; // gain for this session.
F32 mSpeakerVolume; // volume for this session.
bool mShuttingDown;
@ -382,7 +380,6 @@ public:
static void predSendData(const LLWebRTCVoiceClient::sessionStatePtr_t &session, const std::string& spatial_data);
static void predUpdateOwnVolume(const LLWebRTCVoiceClient::sessionStatePtr_t &session, F32 audio_level);
static void predSetMuteMic(const LLWebRTCVoiceClient::sessionStatePtr_t &session, bool mute);
static void predSetMicGain(const LLWebRTCVoiceClient::sessionStatePtr_t &session, F32 volume);
static void predSetSpeakerVolume(const LLWebRTCVoiceClient::sessionStatePtr_t &session, F32 volume);
static void predShutdownSession(const LLWebRTCVoiceClient::sessionStatePtr_t &session);
static void predSetUserMute(const LLWebRTCVoiceClient::sessionStatePtr_t &session, const LLUUID& id, bool mute);
@ -607,7 +604,6 @@ class LLVoiceWebRTCConnection :
void processIceUpdatesCoro();
virtual void setMuteMic(bool muted);
virtual void setMicGain(F32 volume);
virtual void setSpeakerVolume(F32 volume);
void setUserVolume(const LLUUID& id, F32 volume);
@ -686,7 +682,6 @@ class LLVoiceWebRTCConnection :
std::string mRemoteChannelSDP;
bool mMuted;
F32 mMicGain;
F32 mSpeakerVolume;
bool mShutDown;

View File

@ -103,13 +103,6 @@
<menu_item_check label="Gesten" name="Gestures"/>
<menu_item_call label="Twitter..." name="Twitter"/>
<menu_item_call label="Flickr..." name="Flickr"/>
<menu_item_call label="Discord..." name="Discord"/>
<menu label="Voice-Morphing" name="VoiceMorphing">
<menu_item_check label="Kein Voice-Morphing" name="NoVoiceMorphing"/>
<menu_item_check label="Vorschau..." name="Preview"/>
<menu_item_call label="Abonnieren..." name="Subscribe"/>
<menu_item_call label="Premium-Vorteil..." name="PremiumPerk"/>
</menu>
<menu_item_check label="Unterhaltungsprotokoll..." name="Conversation Log..."/>
<menu_item_check label="Stimmen in der Nähe" name="Nearby Voice"/>
<menu_item_call label="Blockierliste" name="Block List"/>

View File

@ -847,42 +847,6 @@
parameter="fs_discord"/>
</menu_item_call>
<menu_item_separator/>
<menu
label="Voice morphing"
name="VoiceMorphing"
visibility_control="VoiceMorphingEnabled">
<menu_item_check
label="No voice morphing"
name="NoVoiceMorphing">
<menu_item_check.on_check
function="Communicate.VoiceMorphing.NoVoiceMorphing.Check" />
<menu_item_check.on_click
function="Communicate.VoiceMorphing.NoVoiceMorphing.Click" />
</menu_item_check>
<menu_item_separator/>
<menu_item_check
label="Preview..."
name="Preview">
<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_item_call
label="Subscribe..."
name="Subscribe">
<menu_item_call.on_click
function="Communicate.VoiceMorphing.Subscribe" />
</menu_item_call>
<menu_item_call
label="Premium perk..."
name="PremiumPerk">
<menu_item_call.on_click
function="Communicate.VoiceMorphing.PremiumPerk" />
</menu_item_call>
</menu>
<menu_item_check
name="Conversation Log..."
label="Conversation Log...">

View File

@ -9487,6 +9487,20 @@ New Voice Morphs are available!
<tag>voice</tag>
</notification>
<notification
icon="alertmodal.tga"
name="VoiceEffectsNotSupported"
sound="UISndAlert"
persist="true"
type="alertmodal">
Voice Morphs are not supported by this viewer.
<usetemplate
notext="Cancel"
name="okcancelbuttons"
yestext="Disable Voice Morphing"/>
<tag>voice</tag>
</notification>
<notification
icon="notifytip.tga"
name="Cannot enter parcel: not a group member"

View File

@ -1111,7 +1111,6 @@
</text>
<combo_box
control_name="VoiceNoiseSuppressionLevel"
enabled_control="AudioStreamingMedia"
layout="topleft"
height="23"
left_pad="10"

View File

@ -69,11 +69,6 @@
<menu_item_check label="Gente" name="People"/>
<menu_item_check label="Conversaciones" name="Conversations"/>
<menu_item_check label="Gestos" name="Gestures"/>
<menu label="Filtro de voz" name="VoiceMorphing">
<menu_item_check label="Sin filtro de voz" name="NoVoiceMorphing"/>
<menu_item_check label="Probar..." name="Preview"/>
<menu_item_call label="Suscribir..." name="Subscribe"/>
</menu>
<menu_item_check name="Conversation Log..." label="Registro de conversaciones..."/>
<menu_item_check label="Chat de voz" name="Nearby Voice"/>
<menu_item_call label="Lista de bloqueados" name="Block List"/>

View File

@ -92,12 +92,6 @@
<menu_item_check label="Persone" name="People"/>
<menu_item_check label="Conversazioni" name="Conversations"/>
<menu_item_check label="Gesti" name="Gestures"/>
<menu label="Modifica voce" name="VoiceMorphing">
<menu_item_check label="Nessuna modifica" name="NoVoiceMorphing"/>
<menu_item_check label="Anteprima..." name="Preview"/>
<menu_item_call label="Iscrizione..." name="Subscribe"/>
<menu_item_call label="Offerta Premium..." name="PremiumPerk"/>
</menu>
<menu_item_check label="Storico Conversazioni" name="Conversation Log..."/>
<menu_item_check label="Voce nelle vicinanze" name="Nearby Voice"/>
<menu_item_call label="Lista Bloccati" name="Block List"/>

View File

@ -108,14 +108,6 @@
<menu_item_call label="Twitter..." name="Twitter" />
<menu_item_call label="Flickr..." name="Flickr" />
<menu_item_call label="Discord..." name="Discord"/>
<menu_item_separator/>
<menu label="ボイスモーフィング" name="VoiceMorphing">
<menu_item_check label="ボイスモーフィングなし" name="NoVoiceMorphing" />
<menu_item_separator/>
<menu_item_check label="プレビュー..." name="Preview" />
<menu_item_call label="購入..." name="Subscribe" />
<menu_item_call label="プレミアム特典..." name="PremiumPerk" />
</menu>
<menu_item_check name="Conversation Log..." label="会話ログ..." />
<menu_item_check label="近くのボイス" name="Nearby Voice"/>
<menu_item_call label="ブロックリスト" name="Block List"/>

View File

@ -92,12 +92,6 @@
<menu_item_check label="Ludzie" name="People"/>
<menu_item_check label="Rozmowy" name="Conversations"/>
<menu_item_check label="Gesty" name="Gestures"/>
<menu label="Przekształcanie głosu" name="VoiceMorphing">
<menu_item_check label="Bez przekształcania" name="NoVoiceMorphing"/>
<menu_item_check label="Podgląd..." name="Preview"/>
<menu_item_call label="Subskrybuj..." name="Subscribe"/>
<menu_item_call label="Korzyści premium..." name="PremiumPerk" />
</menu>
<menu_item_check name="Conversation Log..." label="Dziennik rozmów..."/>
<menu_item_check label="Głos w pobliżu" name="Nearby Voice"/>
<menu_item_call label="Lista zablokowanych" name="Block List"/>

View File

@ -43,12 +43,6 @@
<menu_item_check label="Bate-papo local..." name="Nearby Chat"/>
<menu_item_check label="Falar" name="Speak"/>
<menu_item_check label="Registro de conversas..." name="Conversation Log..."/>
<menu label="Distorção de voz" name="VoiceMorphing">
<menu_item_check label="Não distorcer voz" name="NoVoiceMorphing"/>
<menu_item_check label="Visualizar..." name="Preview"/>
<menu_item_call label="Assinar..." name="Subscribe"/>
<menu_item_call label="Benefício Premium..." name="PremiumPerk"/>
</menu>
<menu_item_check label="Gestos..." name="Gestures"/>
<menu_item_check label="Amigos" name="My Friends"/>
<menu_item_check label="Grupos" name="My Groups"/>

View File

@ -103,12 +103,6 @@
<menu_item_check label="Люди" name="People"/>
<menu_item_check label="Разговоры" name="Conversations"/>
<menu_item_check label="Жесты" name="Gestures"/>
<menu label="Изменение голоса" name="VoiceMorphing">
<menu_item_check label="Нет изменений голоса" name="NoVoiceMorphing"/>
<menu_item_check label="Предварительный просмотр..." name="Preview"/>
<menu_item_call label="Подписаться..." name="Subscribe"/>
<menu_item_call label="Премиум привилегия..." name="PremiumPerk"/>
</menu>
<menu_item_check name="Conversation Log..." label="Журнал разговоров..."/>
<menu_item_check label="Ближайшие голоса" name="Nearby Voice"/>
<menu_item_call label="Список заблокированных" name="Block List"/>

View File

@ -37,12 +37,6 @@
<menu_item_check label="Yakındaki Sohbet..." name="Nearby Chat"/>
<menu_item_check label="Konuş" name="Speak"/>
<menu_item_check label="Sohbet Günlüğü..." name="Conversation Log..."/>
<menu label="Ses şekillendirme" name="VoiceMorphing">
<menu_item_check label="Ses şekillendirme yok" name="NoVoiceMorphing"/>
<menu_item_check label="Önizleme..." name="Preview"/>
<menu_item_call label="Abone ol..." name="Subscribe"/>
<menu_item_call label="Özel üye avantajı..." name="PremiumPerk"/>
</menu>
<menu_item_check label="Mimikler..." name="Gestures"/>
<menu_item_check label="Arkadaşlar" name="My Friends"/>
<menu_item_check label="Gruplar" name="My Groups"/>

View File

@ -37,12 +37,6 @@
<menu_item_check label="附近的聊天……" name="Nearby Chat"/>
<menu_item_check label="說話" name="Speak"/>
<menu_item_check label="交談記錄…" name="Conversation Log..."/>
<menu label="語音變聲" name="VoiceMorphing">
<menu_item_check label="沒有變聲效果" name="NoVoiceMorphing"/>
<menu_item_check label="預覽……" name="Preview"/>
<menu_item_call label="訂閱……" name="Subscribe"/>
<menu_item_call label="付費會員獨享…" name="PremiumPerk"/>
</menu>
<menu_item_check label="姿勢…" name="Gestures"/>
<menu_item_check label="朋友" name="My Friends"/>
<menu_item_check label="群組" name="My Groups"/>