diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index c8bb4aa983dea38cd2835c350bad3c5702718424..9da3db303286ca955249ca9c5c14727a01b51ad8 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -529,6 +529,7 @@ BOOL LLSpeakerMgr::isVoiceActive()
 // LLIMSpeakerMgr
 //
 LLIMSpeakerMgr::LLIMSpeakerMgr(LLVoiceChannel* channel) : LLSpeakerMgr(channel)
+, mVoiceModerated(false)
 {
 }
 
@@ -783,21 +784,33 @@ void LLIMSpeakerMgr::moderateVoiceOtherParticipants(const LLUUID& excluded_avata
 	*/
 
 	mReverseVoiceModeratedAvatarID = excluded_avatar_id;
-	moderateVoiceSession(getSessionID(), !unmute_everyone_else);
+
+
+	if (mVoiceModerated == !unmute_everyone_else)
+	{
+		// session already in requested state. Just force participants which do not match it.
+		forceVoiceModeratedMode(mVoiceModerated);
+	}
+	else
+	{
+		// otherwise set moderated mode for a whole session.
+		moderateVoiceSession(getSessionID(), !unmute_everyone_else);
+	}
 }
 
 void LLIMSpeakerMgr::processSessionUpdate(const LLSD& session_update)
 {
-	if (mReverseVoiceModeratedAvatarID.isNull()) return;
-
 	if (session_update.has("moderated_mode") &&
 		session_update["moderated_mode"].has("voice"))
 	{
-		BOOL voice_moderated = session_update["moderated_mode"]["voice"];
+		mVoiceModerated = session_update["moderated_mode"]["voice"];
 
-		moderateVoiceParticipant(mReverseVoiceModeratedAvatarID, voice_moderated);
+		if (mReverseVoiceModeratedAvatarID.notNull())
+		{
+			moderateVoiceParticipant(mReverseVoiceModeratedAvatarID, mVoiceModerated);
 
-		mReverseVoiceModeratedAvatarID = LLUUID::null;
+			mReverseVoiceModeratedAvatarID = LLUUID::null;
+		}
 	}
 }
 
@@ -817,6 +830,20 @@ void LLIMSpeakerMgr::moderateVoiceSession(const LLUUID& session_id, bool disallo
 	LLHTTPClient::post(url, data, new ModerationResponder(session_id));
 }
 
+void LLIMSpeakerMgr::forceVoiceModeratedMode(bool should_be_muted)
+{
+	for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end(); ++speaker_it)
+	{
+		LLUUID speaker_id = speaker_it->first;
+		LLSpeaker* speakerp = speaker_it->second;
+
+		// participant does not match requested state
+		if (should_be_muted != (bool)speakerp->mModeratorMutedVoice)
+		{
+			moderateVoiceParticipant(speaker_id, !should_be_muted);
+		}
+	}
+}
 
 //
 // LLActiveSpeakerMgr
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index 2bb160b7ce9d4b6264ece7cb3ec506dcf8b68a7b..b38acb7bc4d04ae2614f5f49e9f01fd512f99805 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -303,7 +303,15 @@ class LLIMSpeakerMgr : public LLSpeakerMgr
 
 	void moderateVoiceSession(const LLUUID& session_id, bool disallow_voice);
 
+	/**
+	 * Process all participants to mute/unmute them according to passed voice session state.
+	 */
+	void forceVoiceModeratedMode(bool should_be_muted);
+
+private:
 	LLUUID mReverseVoiceModeratedAvatarID;
+	bool mVoiceModerated;
+
 };
 
 class LLActiveSpeakerMgr : public LLSpeakerMgr, public LLSingleton<LLActiveSpeakerMgr>