diff options
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/llvoiceclient.h | 12 | ||||
-rw-r--r-- | indra/newview/llvoicevivox.cpp | 233 | ||||
-rw-r--r-- | indra/newview/llvoicevivox.h | 30 |
3 files changed, 272 insertions, 3 deletions
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; }; /** |