STORM-591 As a music fan, I want audio to fade in gently so my immersion is increased

Co-written with Robin Cornelius
master
Jonathan Yap 2011-10-28 17:48:24 -04:00
parent 1b173ed82b
commit 4cdf396125
10 changed files with 322 additions and 529 deletions

View File

@ -581,6 +581,7 @@ Jonathan Yap
STORM-1639
STORM-910
STORM-1642
STORM-591
Kadah Coba
STORM-1060
Jondan Lundquist
@ -913,6 +914,7 @@ Robin Cornelius
SNOW-599
SNOW-747
STORM-422
STORM-591
STORM-960
STORM-1019
STORM-1095

View File

@ -192,6 +192,28 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>AudioMusicFadeIn</key>
<map>
<key>Comment</key>
<string>Fade in time in seconds for music streams</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>5.0</real>
</map>
<key>AudioMusicFadeOut</key>
<map>
<key>Comment</key>
<string>Fade out time in seconds for music streams</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>5.0</real>
</map>
<key>AudioLevelAmbient</key>
<map>
<key>Comment</key>

View File

@ -1,378 +0,0 @@
/**
* @file lloverlaybar.cpp
* @brief LLOverlayBar class implementation
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
// Temporary buttons that appear at the bottom of the screen when you
// are in a mode.
#include "llviewerprecompiledheaders.h"
#include "lloverlaybar.h"
#include "llaudioengine.h"
#include "llrender.h"
#include "llagent.h"
#include "llbutton.h"
#include "llfocusmgr.h"
#include "llimview.h"
#include "llmediaremotectrl.h"
#include "llparcel.h"
#include "lltextbox.h"
#include "llui.h"
#include "llviewercontrol.h"
#include "llviewertexturelist.h"
#include "llviewerjoystick.h"
#include "llviewermedia.h"
#include "llviewermenu.h" // handle_reset_view()
#include "llviewermedia.h"
#include "llviewerparcelmedia.h"
#include "llviewerparcelmgr.h"
#include "lluictrlfactory.h"
#include "llviewerwindow.h"
#include "llvoiceclient.h"
#include "llvoavatarself.h"
#include "llvoiceremotectrl.h"
#include "llmediactrl.h"
#include "llselectmgr.h"
//
// Globals
//
LLOverlayBar *gOverlayBar = NULL;
extern S32 MENU_BAR_HEIGHT;
//
// Functions
//
void* LLOverlayBar::createMediaRemote(void* userdata)
{
LLOverlayBar *self = (LLOverlayBar*)userdata;
self->mMediaRemote = new LLMediaRemoteCtrl ();
return self->mMediaRemote;
}
void* LLOverlayBar::createVoiceRemote(void* userdata)
{
LLOverlayBar *self = (LLOverlayBar*)userdata;
self->mVoiceRemote = new LLVoiceRemoteCtrl();
return self->mVoiceRemote;
}
LLOverlayBar::LLOverlayBar()
: LLPanel(),
mMediaRemote(NULL),
mVoiceRemote(NULL),
mMusicState(STOPPED)
{
setMouseOpaque(FALSE);
setIsChrome(TRUE);
mBuilt = false;
mFactoryMap["media_remote"] = LLCallbackMap(LLOverlayBar::createMediaRemote, this);
mFactoryMap["voice_remote"] = LLCallbackMap(LLOverlayBar::createVoiceRemote, this);
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_overlaybar.xml");
}
BOOL LLOverlayBar::postBuild()
{
childSetAction("Set Not Busy",onClickSetNotBusy,this);
childSetAction("Mouselook",onClickMouselook,this);
childSetAction("Stand Up",onClickStandUp,this);
childSetAction("Flycam",onClickFlycam,this);
childSetVisible("chat_bar", gSavedSettings.getBOOL("ChatVisible"));
mVoiceRemote->expandOrCollapse();
mMediaRemote->expandOrCollapse();
setFocusRoot(TRUE);
mBuilt = true;
layoutButtons();
return TRUE;
}
LLOverlayBar::~LLOverlayBar()
{
// LLView destructor cleans up children
}
// virtual
void LLOverlayBar::reshape(S32 width, S32 height, BOOL called_from_parent)
{
LLView::reshape(width, height, called_from_parent);
if (mBuilt)
{
layoutButtons();
}
}
void LLOverlayBar::layoutButtons()
{
LLView* state_buttons_panel = getChildView("state_buttons");
if (state_buttons_panel->getVisible())
{
LLViewQuery query;
LLWidgetTypeFilter<LLButton> widget_filter;
query.addPreFilter(LLEnabledFilter::getInstance());
query.addPreFilter(&widget_filter);
child_list_t button_list = query(state_buttons_panel);
const S32 MAX_BAR_WIDTH = 600;
S32 bar_width = llclamp(state_buttons_panel->getRect().getWidth(), 0, MAX_BAR_WIDTH);
// calculate button widths
const S32 MAX_BUTTON_WIDTH = 150;
const S32 STATUS_BAR_PAD = 10;
S32 segment_width = llclamp(lltrunc((F32)(bar_width) / (F32)button_list.size()), 0, MAX_BUTTON_WIDTH);
S32 btn_width = segment_width - STATUS_BAR_PAD;
// Evenly space all buttons, starting from left
S32 left = 0;
S32 bottom = 1;
for (child_list_reverse_iter_t child_iter = button_list.rbegin();
child_iter != button_list.rend(); ++child_iter)
{
LLView *view = *child_iter;
LLRect r = view->getRect();
r.setOriginAndSize(left, bottom, btn_width, r.getHeight());
view->setRect(r);
left += segment_width;
}
}
}
// Per-frame updates of visibility
void LLOverlayBar::refresh()
{
BOOL buttons_changed = FALSE;
BOOL im_received = gIMMgr->getIMReceived();
LLButton* button = getChild<LLButton>("IM Received");
if (button && button->getVisible() != im_received)
{
button->setVisible(im_received);
sendChildToFront(button);
moveChildToBackOfTabGroup(button);
buttons_changed = TRUE;
}
BOOL busy = gAgent.getBusy();
button = getChild<LLButton>("Set Not Busy");
if (button && button->getVisible() != busy)
{
button->setVisible(busy);
sendChildToFront(button);
moveChildToBackOfTabGroup(button);
buttons_changed = TRUE;
}
BOOL flycam = LLViewerJoystick::getInstance()->getOverrideCamera();
button = getChild<LLButton>("Flycam");
if (button && button->getVisible() != flycam)
{
button->setVisible(flycam);
sendChildToFront(button);
moveChildToBackOfTabGroup(button);
buttons_changed = TRUE;
}
BOOL mouselook_grabbed;
mouselook_grabbed = gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_DOWN_INDEX)
|| gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_UP_INDEX);
button = getChild<LLButton>("Mouselook");
if (button && button->getVisible() != mouselook_grabbed)
{
button->setVisible(mouselook_grabbed);
sendChildToFront(button);
moveChildToBackOfTabGroup(button);
buttons_changed = TRUE;
}
BOOL sitting = FALSE;
if (gAgent.getAvatarObject())
{
sitting = gAgent.getAvatarObject()->isSitting();
}
button = getChild<LLButton>("Stand Up");
if (button && button->getVisible() != sitting)
{
button->setVisible(sitting);
sendChildToFront(button);
moveChildToBackOfTabGroup(button);
buttons_changed = TRUE;
}
moveChildToBackOfTabGroup(mMediaRemote);
moveChildToBackOfTabGroup(mVoiceRemote);
// turn off the whole bar in mouselook
if (gAgent.cameraMouselook())
{
childSetVisible("media_remote_container", FALSE);
childSetVisible("voice_remote_container", FALSE);
childSetVisible("state_buttons", FALSE);
}
else
{
// update "remotes"
childSetVisible("media_remote_container", TRUE);
childSetVisible("voice_remote_container", LLVoiceClient::getInstance()->voiceEnabled());
childSetVisible("state_buttons", TRUE);
}
// always let user toggle into and out of chatbar
childSetVisible("chat_bar", gSavedSettings.getBOOL("ChatVisible"));
if (buttons_changed)
{
layoutButtons();
}
}
//-----------------------------------------------------------------------
// Static functions
//-----------------------------------------------------------------------
// static
void LLOverlayBar::onClickSetNotBusy(void*)
{
gAgent.clearBusy();
}
// static
void LLOverlayBar::onClickFlycam(void*)
{
LLViewerJoystick::getInstance()->toggleFlycam();
}
// static
void LLOverlayBar::onClickResetView(void* data)
{
handle_reset_view();
}
//static
void LLOverlayBar::onClickMouselook(void*)
{
gAgent.changeCameraToMouselook();
}
//static
void LLOverlayBar::onClickStandUp(void*)
{
LLSelectMgr::getInstance()->deselectAllForStandingUp();
gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
}
////////////////////////////////////////////////////////////////////////////////
// static media helpers
// *TODO: Move this into an audio manager abstraction
//static
void LLOverlayBar::mediaStop(void*)
{
if (!gOverlayBar)
{
// return;
}
LLViewerParcelMedia::stop();
}
//static
void LLOverlayBar::toggleMediaPlay(void*)
{
if (!gOverlayBar)
{
// return;
}
if (LLViewerParcelMedia::getStatus() == LLViewerMediaImpl::MEDIA_PAUSED)
{
LLViewerParcelMedia::start();
}
else if(LLViewerParcelMedia::getStatus() == LLViewerMediaImpl::MEDIA_PLAYING)
{
LLViewerParcelMedia::pause();
}
else
{
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
if (parcel)
{
LLViewerParcelMedia::play(parcel);
}
}
}
//static
void LLOverlayBar::toggleMusicPlay(void*)
{
if (gAudiop->isInternetStreamPlaying() != 1)
{
if (gAudiop)
{
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
if ( parcel )
{
// this doesn't work properly when crossing parcel boundaries - even when the
// stream is stopped, it doesn't return the right thing - commenting out for now.
// if ( gAudiop->isInternetStreamPlaying() == 0 )
{
gAudiop->startInternetStream(parcel->getMusicURL());
}
}
}
}
//else
//{
// gOverlayBar->mMusicState = PAUSED; // desired state
// if (gAudiop)
// {
// gAudiop->pauseInternetStream(1);
// }
//}
else
{
if (gAudiop)
{
gAudiop->stopInternetStream();
}
}
}

View File

@ -1,95 +0,0 @@
/**
* @file lloverlaybar.h
* @brief LLOverlayBar class definition
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLOVERLAYBAR_H
#define LL_LLOVERLAYBAR_H
#include "llpanel.h"
// "Constants" loaded from settings.xml at start time
extern S32 STATUS_BAR_HEIGHT;
class LLButton;
class LLLineEditor;
class LLMediaRemoteCtrl;
class LLMessageSystem;
class LLTextBox;
class LLTextEditor;
class LLUICtrl;
class LLUUID;
class LLFrameTimer;
class LLStatGraph;
class LLSlider;
class LLVoiceRemoteCtrl;
class LLOverlayBar
: public LLPanel
{
public:
LLOverlayBar();
~LLOverlayBar();
/*virtual*/ void refresh();
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
/*virtual*/ BOOL postBuild();
void layoutButtons();
// helpers for returning desired state
BOOL musicPlaying() { return mMusicState == PLAYING; }
static void onClickSetNotBusy(void* data);
static void onClickMouselook(void* data);
static void onClickStandUp(void* data);
static void onClickResetView(void* data);
static void onClickFlycam(void* data);
//static media helper functions
static void toggleMediaPlay(void*);
static void toggleMusicPlay(void*);
static void musicPause(void*);
static void musicStop(void*);
static void mediaStop(void*);
static void toggleAudioVolumeFloater(void*);
protected:
static void* createMediaRemote(void* userdata);
static void* createVoiceRemote(void* userdata);
void enableMediaButtons();
protected:
LLMediaRemoteCtrl* mMediaRemote;
LLVoiceRemoteCtrl* mVoiceRemote;
bool mBuilt; // dialog constructed yet?
enum { STOPPED=0, PLAYING=1, PAUSED=2 };
S32 mMusicState;
};
extern LLOverlayBar* gOverlayBar;
#endif

View File

@ -52,6 +52,7 @@
#include "llvovolume.h"
#include "llstatusbar.h"
#include "llsdutil.h"
#include "llvieweraudio.h"
#include "llfloaterreg.h"
#include "llfloaterpreference.h" // for the gear icon
@ -808,7 +809,7 @@ bool LLPanelNearByMedia::setDisabled(const LLUUID &row_id, bool disabled)
if (row_id == PARCEL_AUDIO_LIST_ITEM_UUID)
{
if (disabled) onClickParcelAudioStop();
else onClickParcelAudioStart();
else onClickParcelAudioPlay();
return true;
}
else if (row_id == PARCEL_MEDIA_LIST_ITEM_UUID)
@ -857,24 +858,11 @@ void LLPanelNearByMedia::onClickParcelMediaPause()
LLViewerParcelMedia::pause();
}
void LLPanelNearByMedia::onClickParcelAudioStart()
{
// User *explicitly* started the internet stream, so keep the stream
// playing and updated as they cross to other parcels etc.
mParcelAudioAutoStart = true;
if (!gAudiop)
return;
gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL());
}
void LLPanelNearByMedia::onClickParcelAudioPlay()
{
// User *explicitly* started the internet stream, so keep the stream
// playing and updated as they cross to other parcels etc.
mParcelAudioAutoStart = true;
if (!gAudiop)
return;
@ -883,8 +871,9 @@ void LLPanelNearByMedia::onClickParcelAudioPlay()
// 'false' means unpause
gAudiop->pauseInternetStream(false);
}
else {
gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL());
else
{
LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLViewerMedia::getParcelAudioURL());
}
}
@ -894,11 +883,10 @@ void LLPanelNearByMedia::onClickParcelAudioStop()
// re-start audio when i.e. they move to another parcel, until
// they explicitly start it again.
mParcelAudioAutoStart = false;
if (!gAudiop)
return;
gAudiop->stopInternetStream();
LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade();
}
void LLPanelNearByMedia::onClickParcelAudioPause()

View File

@ -115,7 +115,6 @@ private:
void onClickParcelMediaPause();
void onClickParcelAudioPlay();
void onClickParcelAudioStop();
void onClickParcelAudioStart();
void onClickParcelAudioPause();
void onCheckAutoPlay();
void onAdvancedButtonClick();

View File

@ -37,9 +37,212 @@
#include "llvoiceclient.h"
#include "llviewermedia.h"
#include "llprogressview.h"
#include "llcallbacklist.h"
/////////////////////////////////////////////////////////
LLViewerAudio::LLViewerAudio() :
mDone(true),
mFadeState(FADE_IDLE),
mFadeTime(),
mIdleListnerActive(false)
{
}
LLViewerAudio::~LLViewerAudio()
{
}
void LLViewerAudio::registerIdleListener()
{
if(mIdleListnerActive==false)
{
mIdleListnerActive = true;
doOnIdleRepeating(boost::bind(boost::bind(&LLViewerAudio::onIdleUpdate, this)));
}
}
void LLViewerAudio::startInternetStreamWithAutoFade(std::string streamURI)
{
llinfos << "DBG streamURI: " << streamURI << llendl;
llinfos << "DBG mNextStreamURI: " << mNextStreamURI << llendl;
if (mFadeState == FADE_OUT) {llinfos << "DBG mFadeState: FADE_OUT " << llendl;}
if (mFadeState == FADE_IN) {llinfos << "DBG mFadeState: FADE_IN " << llendl;}
if (mFadeState == FADE_IDLE) {llinfos << "DBG mFadeState: FADE_IDLE " << llendl;}
// Old and new stream are identical
if (mNextStreamURI == streamURI)
{
return;
}
// Record the URI we are going to be switching to
mNextStreamURI = streamURI;
if (mFadeState == FADE_IDLE)
{
// If a stream is playing fade it out first
if (!gAudiop->getInternetStreamURL().empty())
{
mFadeState = FADE_OUT;
llinfos << "DBG new mFadeState: OUT" << llendl;
}
// Otherwise the new stream can be faded in
else
{
mFadeState = FADE_IN;
llinfos << "DBG new mFadeState: IN" << llendl;
gAudiop->startInternetStream(mNextStreamURI);
startFading();
registerIdleListener();
return;
}
}
if (mFadeState == FADE_OUT)
{
startFading();
registerIdleListener();
return;
}
if (mFadeState == FADE_IN)
{
registerIdleListener();
return;
}
}
// We want onIdleUpdate callback to keep firing whilst we are fading out. Once we have completed the fade
// out, we switch the stream and start a fade in, and we don't care about idle updates anymore.
// A return of false from onIdleUpdate means it will be called again next idle update.
// A return of true means we have finished with it and the callback will be deleted.
bool LLViewerAudio::onIdleUpdate()
{
if (mDone)
{
if (mFadeState == FADE_OUT) {llinfos << "DBG mFadeState: FADE_OUT " << llendl;}
if (mFadeState == FADE_IN) {llinfos << "DBG mFadeState: FADE_IN " << llendl;}
if (mFadeState == FADE_IDLE) {llinfos << "DBG mFadeState: FADE_IDLE " << llendl;}
// This should be a rare or never occurring state.
if (mFadeState == FADE_IDLE)
{
deregisterIdleListener();
return true; // Stop calling onIdleUpdate
}
// we have finished the current fade operation
if (mFadeState == FADE_OUT)
{
// Clear URI
gAudiop->startInternetStream(LLStringUtil::null);
gAudiop->stopInternetStream();
if (!mNextStreamURI.empty())
{
mFadeState = FADE_IN;
llinfos << "DBG new mFadeState: IN" << llendl;
gAudiop->startInternetStream(mNextStreamURI);
startFading();
return false;
}
else
{
mFadeState = FADE_IDLE;
llinfos << "DBG new mFadeState: IDLE" << llendl;
deregisterIdleListener();
return true; // Stop calling onIdleUpdate
}
}
else if (mFadeState == FADE_IN)
{
if (mNextStreamURI != gAudiop->getInternetStreamURL())
{
mFadeState = FADE_OUT;
startFading();
return false;
llinfos << "DBG new mFadeState: OUT" << llendl;
}
else
{
mFadeState = FADE_IDLE;
llinfos << "DBG new mFadeState: IDLE" << llendl;
deregisterIdleListener();
return true; // Stop calling onIdleUpdate
}
}
}
return false;
}
void LLViewerAudio::stopInternetStreamWithAutoFade()
{
llinfos << "DBG stopping stream" << llendl;
mFadeState = FADE_IDLE;
llinfos << "DBG new mFadeState: IDLE" << llendl;
mNextStreamURI = LLStringUtil::null;
mDone = true;
llinfos << "DBG mDone: true" << llendl;
gAudiop->startInternetStream(LLStringUtil::null);
gAudiop->stopInternetStream();
}
void LLViewerAudio::startFading()
{
llinfos << "DBG startFading" << llendl;
if(mDone)
{
// The fade state here should only be one of FADE_IN or FADE_OUT, but, in case it is not,
// rather than check for both states assume a fade in and check for the fade out case.
mFadeTime = llmax(0.0f, gSavedSettings.getF32("AudioMusicFadeIn"));
if (LLViewerAudio::getInstance()->getFadeState() == LLViewerAudio::FADE_OUT)
{
mFadeTime = llmax(0.0f, gSavedSettings.getF32("AudioMusicFadeOut"));
}
stream_fade_timer.reset();
stream_fade_timer.setTimerExpirySec(mFadeTime);
mDone = false;
llinfos << "DBG mDone: false" << llendl;
}
}
F32 LLViewerAudio::getFadeVolume()
{
F32 fade_volume = 1.0f;
if (stream_fade_timer.hasExpired())
{
mDone = true;
// If we have been fading out set volume to 0 until the next fade state occurs to prevent
// an audio transient.
if (LLViewerAudio::getInstance()->getFadeState() == LLViewerAudio::FADE_OUT)
{
fade_volume = 0.0f;
}
}
if (!mDone)
{
// Calculate how far we are into the fade time
fade_volume = stream_fade_timer.getElapsedTimeF32() / mFadeTime;
if (LLViewerAudio::getInstance()->getFadeState() == LLViewerAudio::FADE_OUT)
{
// If we are not fading in then we are fading out, so invert the fade
// direction; start loud and move towards zero volume.
fade_volume = 1.0f - fade_volume;
}
}
return fade_volume;
}
void init_audio()
{
if (!gAudiop)
@ -145,9 +348,11 @@ void audio_update_volume(bool force_update)
{
F32 music_volume = gSavedSettings.getF32("AudioLevelMusic");
BOOL music_muted = gSavedSettings.getBOOL("MuteMusic");
music_volume = mute_volume * master_volume * music_volume;
gAudiop->setInternetStreamGain ( music_muted || progress_view_visible ? 0.f : music_volume );
F32 fade_volume = LLViewerAudio::getInstance()->getFadeVolume();
llinfos << "DBG fade_volume:" << fade_volume << llendl;
music_volume = mute_volume * master_volume * music_volume * fade_volume;
gAudiop->setInternetStreamGain (music_muted ? 0.f : music_volume);
}
// Streaming Media

View File

@ -27,6 +27,10 @@
#ifndef LL_VIEWERAUDIO_H
#define LL_VIEWERAUDIO_H
#include "llframetimer.h"
#include "llthread.h"
#include "llsingleton.h"
// comment out to turn off wind
#define kAUDIO_ENABLE_WIND
//#define kAUDIO_ENABLE_WATER 1 // comment out to turn off water
@ -38,4 +42,41 @@ void audio_update_volume(bool force_update = true);
void audio_update_listener();
void audio_update_wind(bool force_update = true);
class LLViewerAudio : public LLSingleton<LLViewerAudio>
{
public:
enum EFadeState
{
FADE_IDLE,
FADE_IN,
FADE_OUT,
};
LLViewerAudio();
virtual ~LLViewerAudio();
void startInternetStreamWithAutoFade(std::string streamURI);
void stopInternetStreamWithAutoFade();
bool LLViewerAudio::onIdleUpdate();
EFadeState getFadeState() { return mFadeState; }
bool isDone() { return mDone; };
F32 getFadeVolume();
private:
bool mDone;
F32 mFadeTime;
std::string mNextStreamURI;
EFadeState mFadeState;
LLFrameTimer stream_fade_timer;
bool mIdleListnerActive;
void registerIdleListener();
void deregisterIdleListener() { mIdleListnerActive = false; };
void startFading();
};
#endif //LL_VIEWER_H

View File

@ -66,7 +66,7 @@
//#include "llfirstuse.h"
#include "llviewernetwork.h"
#include "llwindow.h"
#include "llvieweraudio.h"
#include "llfloatermediabrowser.h" // for handling window close requests and geometry change requests in media browser windows.
#include "llfloaterwebcontent.h" // for handling window close requests and geometry change requests in media browser windows.
@ -967,7 +967,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
{
if(LLViewerMedia::isParcelAudioPlaying() && gAudiop && LLViewerMedia::hasParcelAudio())
{
gAudiop->stopInternetStream();
LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade();
}
}
pimpl->setPriority(new_priority);
@ -1069,13 +1069,24 @@ void LLViewerMedia::setAllMediaEnabled(bool val)
gAudiop &&
LLViewerMedia::hasParcelAudio())
{
gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL());
if (LLAudioEngine::AUDIO_PAUSED == gAudiop->isInternetStreamPlaying())
{
// 'false' means unpause
gAudiop->pauseInternetStream(false);
}
else
{
LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLViewerMedia::getParcelAudioURL());
}
}
}
else {
// This actually unloads the impl, as opposed to "stop"ping the media
LLViewerParcelMedia::stop();
if (gAudiop) gAudiop->stopInternetStream();
if (gAudiop)
{
LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade();
}
}
}
@ -1488,8 +1499,7 @@ void LLViewerMedia::setOpenIDCookie()
new LLViewerMediaWebProfileResponder(raw_profile_url.getAuthority()),
headers);
// FUI: No longer perform the user_status query
//doOnetimeEarlyHTTPRequests();
doOnetimeEarlyHTTPRequests();
}
}

View File

@ -67,6 +67,7 @@
#include "llworld.h"
#include "roles_constants.h"
#include "llweb.h"
#include "llvieweraudio.h"
const F32 PARCEL_COLLISION_DRAW_SECS = 1.f;
@ -1725,7 +1726,11 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
}
else
{
// look for music.
// Check for video
LLViewerParcelMedia::update( parcel );
// Then check for music. Do this last, as there may be a delay waiting for
// the stream fading thread to finish.
if (gAudiop)
{
if (parcel)
@ -1736,46 +1741,36 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
std::string music_url = music_url_raw;
LLStringUtil::trim(music_url);
// On entering a new parcel, stop the last stream if the
// new parcel has a different music url. (Empty URL counts
// as different.)
const std::string& stream_url = gAudiop->getInternetStreamURL();
if (music_url.empty() || music_url != stream_url)
// If there is a new music URL and it's valid, play it.
if (music_url.size() > 12)
{
// URL is different from one currently playing.
gAudiop->stopInternetStream();
// If there is a new music URL and it's valid, play it.
if (music_url.size() > 12)
if (music_url.substr(0,7) == "http://")
{
if (music_url.substr(0,7) == "http://")
{
optionally_start_music(music_url);
}
else
{
llinfos << "Stopping parcel music (invalid audio stream URL)" << llendl;
// clears the URL
gAudiop->startInternetStream(LLStringUtil::null);
}
optionally_start_music(music_url);
}
else if (!gAudiop->getInternetStreamURL().empty())
else
{
llinfos << "Stopping parcel music (parcel stream URL is empty)" << llendl;
gAudiop->startInternetStream(LLStringUtil::null);
llinfos << "Stopping parcel music (invalid audio stream URL)" << llendl;
// clears the URL
// null value causes fade out
LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
}
}
else if (!gAudiop->getInternetStreamURL().empty())
{
llinfos << "Stopping parcel music (parcel stream URL is empty)" << llendl;
// null value causes fade out
LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
}
}
else
{
// Public land has no music
gAudiop->stopInternetStream();
LLViewerAudio::getInstance()->stopInternetStreamWithAutoFade();
}
}//if gAudiop
// now check for video
LLViewerParcelMedia::update( parcel );
};
}
@ -1794,7 +1789,11 @@ void optionally_start_music(const std::string& music_url)
gSavedSettings.getBOOL("MediaTentativeAutoPlay")))
{
llinfos << "Starting parcel music " << music_url << llendl;
gAudiop->startInternetStream(music_url);
LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(music_url);
}
else
{
LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null);
}
}
}