diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index dab57d44bd3ebef0b089ea7654c740d3c69b0302..139eabcae4d37a36290f04ad995c7b0b52c9c81d 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -207,11 +207,11 @@
            icon="Command_Speak_Icon"
            label_ref="Command_Speak_Label"
            tooltip_ref="Command_Speak_Tooltip"
-           execute_function="Floater.ToolbarToggle"
+           execute_function="Agent.ToggleMicrophone"
            execute_parameters="speak"
            is_enabled_function="Agent.IsActionAllowed"
            is_enabled_parameters="speak"
-           is_running_function="Floater.IsOpen"
+           is_running_function="Agent.IsMicrophoneOn"
            is_running_parameters="speak"
            />
   <command name="view"
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index ed29ac796092f83c504cbb4c9312b8f4eadebc94..8303a5942da04b305b139a889b9d1bbd9ed1e355 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -174,12 +174,43 @@ bool LLAgent::isActionAllowed(const LLSD& sdname)
 	}
 	else if (param == "speak")
 	{
-		retval = true;
+		if ( gAgent.isVoiceConnected() )
+		{
+			retval = true;
+		}
+		else
+		{
+			retval = false;
+		}
 	}
 
 	return retval;
 }
 
+// static 
+void LLAgent::toggleMicrophone(const LLSD& name)
+{
+	gAgent.mMicrophoneOn = ! gAgent.mMicrophoneOn;
+
+	if ( gAgent.mMicrophoneOn )
+	{
+		LLFirstUse::speak(false);
+
+		LLVoiceClient::getInstance()->inputUserControlState(true);
+		LLVoiceClient::getInstance()->inputUserControlState(false);
+	}
+	else
+	{
+		LLVoiceClient::getInstance()->inputUserControlState(false);
+		LLVoiceClient::getInstance()->inputUserControlState(true);
+	}
+}
+
+// static
+bool LLAgent::isMicrophoneOn(const LLSD& sdname)
+{
+	return gAgent.mMicrophoneOn;
+}
 
 // ************************************************************
 // Enabled this definition to compile a 'hacked' viewer that
@@ -261,6 +292,9 @@ LLAgent::LLAgent() :
 	mCurrentFidget(0),
 	mFirstLogin(FALSE),
 	mGenderChosen(FALSE),
+	
+	mVoiceConnected(false),
+	mMicrophoneOn(false),
 
 	mAppearanceSerialNum(0),
 
@@ -280,6 +314,8 @@ LLAgent::LLAgent() :
 	LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(boost::bind(&LLAgent::parcelChangedCallback));
 
 	LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Agent.IsActionAllowed", boost::bind(&LLAgent::isActionAllowed, _2));
+	LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Agent.ToggleMicrophone", boost::bind(&LLAgent::toggleMicrophone, _2));
+	LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Agent.IsMicrophoneOn", boost::bind(&LLAgent::isMicrophoneOn, _2));
 }
 
 // Requires gSavedSettings to be initialized.
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 1775a0235cc351fa38be5f7da659fd758fef3c57..0355e68b6e5b78737c79b9def28a2a3421be273b 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -282,7 +282,21 @@ class LLAgent : public LLOldEvents::LLObservable
 	static void		toggleFlying();
 	static bool		enableFlying();
 	BOOL			canFly(); 			// Does this parcel allow you to fly?
-	
+
+	//--------------------------------------------------------------------
+	// Voice
+	//--------------------------------------------------------------------
+public:
+	bool 			isVoiceConnected() const { return mVoiceConnected; }
+	void			setVoiceConnected(const bool b)	{ mVoiceConnected = b; }
+
+	static void		toggleMicrophone(const LLSD& name);
+	static bool		isMicrophoneOn(const LLSD& sdname);
+
+private:
+	bool			mVoiceConnected;
+	bool			mMicrophoneOn;
+
 	//--------------------------------------------------------------------
 	// Chat
 	//--------------------------------------------------------------------
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index 98712f13348f4005e3063ce91d98382b66a2b0c1..af91702f9b8888c0e7da596bf5609bd6ef529989 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -387,6 +387,9 @@ void LLBottomTray::onChange(EStatusType status, const std::string &channelURI, b
 	if (status != STATUS_JOINING && status!= STATUS_LEFT_CHANNEL)
 	{
 		bool voice_status = LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking();
+
+		gAgent.setVoiceConnected(voice_status);
+
 		getChild<LLButton>("speak_flyout_btn")->setEnabled(voice_status);
 		gMenuBarView->getChild<LLView>("Nearby Voice")->setEnabled(voice_status);
 		if (voice_status)