summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorAimee Linden <aimee@lindenlab.com>2010-05-23 02:22:48 +0100
committerAimee Linden <aimee@lindenlab.com>2010-05-23 02:22:48 +0100
commit1ebbe196910110eb51497f272abde277f8f0f69a (patch)
treef3b9ad65823adfb1ce355a5bafbc472915fbbae1 /indra
parent32826f31ebfe19f57a1d8cc7c2f3e81df9b5de74 (diff)
EXT-7337 WIP Voice morph previewing
Separate Play and Stop callbacks, to allow single click previews in the effect list.
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llfloatervoiceeffect.cpp61
-rw-r--r--indra/newview/llfloatervoiceeffect.h4
-rw-r--r--indra/newview/llvoiceclient.h5
-rw-r--r--indra/newview/llvoicevivox.cpp118
-rw-r--r--indra/newview/llvoicevivox.h9
-rw-r--r--indra/newview/skins/default/xui/en/floater_voice_effect.xml4
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>