diff options
Diffstat (limited to 'indra')
-rw-r--r-- | indra/newview/llfloatervoiceeffect.cpp | 61 | ||||
-rw-r--r-- | indra/newview/llfloatervoiceeffect.h | 4 | ||||
-rw-r--r-- | indra/newview/llvoiceclient.h | 5 | ||||
-rw-r--r-- | indra/newview/llvoicevivox.cpp | 118 | ||||
-rw-r--r-- | indra/newview/llvoicevivox.h | 9 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/floater_voice_effect.xml | 4 |
6 files changed, 142 insertions, 59 deletions
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> |