diff --git a/indra/llaudio/llstreamingaudio.h b/indra/llaudio/llstreamingaudio.h index 4ceb037e09fe7ed2e64f046e53d9e981efe72b5f..897f0d06c5c2771032c0a0ea5b1420355c4bf696 100644 --- a/indra/llaudio/llstreamingaudio.h +++ b/indra/llaudio/llstreamingaudio.h @@ -30,6 +30,10 @@ #include "stdtypes.h" // from llcommon +#include "llsd.h" + +#include "boost/signals2.hpp" + class LLSD; // Entirely abstract. Based exactly on the historic API. @@ -52,10 +56,18 @@ class LLStreamingAudioInterface virtual void setBufferSizes(U32 streambuffertime, U32 decodebuffertime) = 0; virtual bool supportsMetaData() = 0; - virtual const LLSD *getMetaData() = 0; - virtual bool hasNewMetaData() = 0; + using metadata_signal_t = boost::signals2::signal<void(const LLSD& metadata)>; + virtual boost::signals2::connection setMetadataUpdatedCallback(const metadata_signal_t::slot_type& cb) + { + return mMetadataUpdateSignal.connect(cb); + } + virtual LLSD getMetadata() const { return LLSD(); } + virtual bool supportsWaveData() = 0; virtual bool getWaveData(float* arr, S32 count, S32 stride = 1) = 0; + +protected: + metadata_signal_t mMetadataUpdateSignal; }; #endif // LL_STREAMINGAUDIO_H diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.cpp b/indra/llaudio/llstreamingaudio_fmodstudio.cpp index 817ddc509ba1a2c0a35705990d7ce7466cc2fcd2..faf575af23a8f35b65e4c8a86a4318dcf27c1888 100644 --- a/indra/llaudio/llstreamingaudio_fmodstudio.cpp +++ b/indra/llaudio/llstreamingaudio_fmodstudio.cpp @@ -117,8 +117,7 @@ LLStreamingAudio_FMODSTUDIO::LLStreamingAudio_FMODSTUDIO(FMOD::System *system) : mFMODInternetStreamChannelp(nullptr), mGain(1.0f), mWasAlreadyPlaying(false), - mMetaData(nullptr), - mNewMetadata(true) + mMetadata(LLSD::emptyMap()) { // Number of milliseconds of audio to buffer for the audio card. // Must be larger than the usual Second Life frame stutter time. @@ -168,7 +167,6 @@ void LLStreamingAudio_FMODSTUDIO::start(const std::string& url) LL_INFOS() << "Starting internet stream: " << url << LL_ENDL; mCurrentInternetStreamp = new LLAudioStreamManagerFMODSTUDIO(mSystem, mStreamGroup, url); mURL = url; - mMetaData = new LLSD; } else { @@ -237,7 +235,8 @@ void LLStreamingAudio_FMODSTUDIO::update() LL_INFOS() << "Starting internet stream: " << mPendingURL << LL_ENDL; mCurrentInternetStreamp = new LLAudioStreamManagerFMODSTUDIO(mSystem, mStreamGroup, mPendingURL); mURL = mPendingURL; - mMetaData = new LLSD; + mMetadata = LLSD::emptyMap(); + mMetadataUpdateSignal(mMetadata); mPendingURL.clear(); } @@ -294,19 +293,15 @@ void LLStreamingAudio_FMODSTUDIO::update() if (mFMODInternetStreamChannelp) { - if(!mMetaData) - mMetaData = new LLSD; - FMOD::Sound *sound = nullptr; if(mFMODInternetStreamChannelp->getCurrentSound(&sound) == FMOD_OK && sound) { FMOD_TAG tag; S32 tagcount, dirtytagcount; - if(sound->getNumTags(&tagcount, &dirtytagcount) == FMOD_OK && dirtytagcount) + if(sound->getNumTags(&tagcount, &dirtytagcount) == FMOD_OK && dirtytagcount > 0) { - mMetaData->clear(); - mNewMetadata = true; + mMetadata = LLSD::emptyMap(); for(S32 i = 0; i < tagcount; ++i) { @@ -352,11 +347,11 @@ void LLStreamingAudio_FMODSTUDIO::update() switch (tag.datatype) { case(FMOD_TAGDATATYPE_INT): - (*mMetaData)[name]=*(LLSD::Integer*)(tag.data); + mMetadata[name]=*(LLSD::Integer*)(tag.data); LL_INFOS() << tag.name << ": " << *(int*)(tag.data) << LL_ENDL; break; case(FMOD_TAGDATATYPE_FLOAT): - (*mMetaData)[name]=*(LLSD::Real*)(tag.data); + mMetadata[name]=*(LLSD::Real*)(tag.data); LL_INFOS() << tag.name << ": " << *(float*)(tag.data) << LL_ENDL; break; case(FMOD_TAGDATATYPE_STRING): @@ -364,7 +359,7 @@ void LLStreamingAudio_FMODSTUDIO::update() std::string out = rawstr_to_utf8(std::string((char*)tag.data,tag.datalen)); if (out.length() && out[out.size() - 1] == 0) out.erase(out.size() - 1); - (*mMetaData)[name]=out; + mMetadata[name]=out; LL_INFOS() << tag.name << "(RAW): " << out << LL_ENDL; break; } @@ -376,7 +371,7 @@ void LLStreamingAudio_FMODSTUDIO::update() std::string out((char*)tag.data + offs, tag.datalen - offs); if (out.length() && out[out.size() - 1] == 0) out.erase(out.size() - 1); - (*mMetaData)[name] = out; + mMetadata[name] = out; LL_INFOS() << tag.name << "(UTF8): " << out << LL_ENDL; break; } @@ -385,7 +380,7 @@ void LLStreamingAudio_FMODSTUDIO::update() std::string out = utf16input_to_utf8((unsigned char*)tag.data, tag.datalen, UTF16); if (out.length() && out[out.size() - 1] == 0) out.erase(out.size() - 1); - (*mMetaData)[name] = out; + mMetadata[name] = out; LL_INFOS() << tag.name << "(UTF16): " << out << LL_ENDL; break; } @@ -394,7 +389,7 @@ void LLStreamingAudio_FMODSTUDIO::update() std::string out = utf16input_to_utf8((unsigned char*)tag.data, tag.datalen, UTF16BE); if (out.length() && out[out.size() - 1] == 0) out.erase(out.size() - 1); - (*mMetaData)[name] = out; + mMetadata[name] = out; LL_INFOS() << tag.name << "(UTF16BE): " << out << LL_ENDL; break; } @@ -402,6 +397,8 @@ void LLStreamingAudio_FMODSTUDIO::update() break; } } + + mMetadataUpdateSignal(mMetadata); } if (starving) @@ -428,11 +425,8 @@ void LLStreamingAudio_FMODSTUDIO::stop() mPendingURL.clear(); mWasAlreadyPlaying = false; - if(mMetaData) - { - delete mMetaData; - mMetaData = nullptr; - } + mMetadata = LLSD::emptyMap(); + mMetadataUpdateSignal(mMetadata); if (mFMODInternetStreamChannelp) { @@ -525,19 +519,6 @@ void LLStreamingAudio_FMODSTUDIO::setGain(F32 vol) } } -bool LLStreamingAudio_FMODSTUDIO::hasNewMetaData() -{ - if (mCurrentInternetStreamp && mNewMetadata) - { - mNewMetadata = false; - return true; - } - else - { - return false; - } -} - /* virtual */ bool LLStreamingAudio_FMODSTUDIO::getWaveData(float* arr, S32 count, S32 stride/*=1*/) { diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.h b/indra/llaudio/llstreamingaudio_fmodstudio.h index ccfc16961f6de1c243b624da334819b65fea6fd6..0bc2dc5089a66ff96520f18959fdaafdc60e3e53 100644 --- a/indra/llaudio/llstreamingaudio_fmodstudio.h +++ b/indra/llaudio/llstreamingaudio_fmodstudio.h @@ -31,6 +31,9 @@ #include "llstreamingaudio.h" #include "lltimer.h" +#include "llsd.h" + +#include "boost/signals2.hpp" //Stubs class LLAudioStreamManagerFMODSTUDIO; @@ -62,8 +65,7 @@ class LLStreamingAudio_FMODSTUDIO final : public LLStreamingAudioInterface /*virtual*/ void setBufferSizes(U32 streambuffertime, U32 decodebuffertime) override; /*virtual*/ bool supportsMetaData() override {return true;} - /*virtual*/ const LLSD *getMetaData() override { return mMetaData; } //return NULL if not playing. - /*virtual*/ bool hasNewMetaData() override; + /*virtual*/ LLSD getMetadata() const override { return mMetadata; } //return NULL if not playing. /*virtual*/ bool supportsWaveData() override {return true;} /*virtual*/ bool getWaveData(float* arr, S32 count, S32 stride = 1) override; private: @@ -84,8 +86,7 @@ class LLStreamingAudio_FMODSTUDIO final : public LLStreamingAudioInterface bool mWasAlreadyPlaying; - LLSD *mMetaData; - bool mNewMetadata; + LLSD mMetadata; }; diff --git a/indra/newview/alpanelmusicticker.cpp b/indra/newview/alpanelmusicticker.cpp index 9dd56825cddac464fba209f1d6f6433254627b31..24281af50cd837474214c1edbb0803f8c09dc642 100644 --- a/indra/newview/alpanelmusicticker.cpp +++ b/indra/newview/alpanelmusicticker.cpp @@ -46,6 +46,14 @@ ALPanelMusicTicker::ALPanelMusicTicker() : LLPanel(), { } +ALPanelMusicTicker::~ALPanelMusicTicker() +{ + if (mMetadataUpdateConnection.connected()) + { + mMetadataUpdateConnection.disconnect(); + } +} + BOOL ALPanelMusicTicker::postBuild() { mArtistText = getChild<LLTextBox>("artist_text"); @@ -54,8 +62,17 @@ BOOL ALPanelMusicTicker::postBuild() mszLoading = getString("loading"); mszPaused = getString("paused"); mOscillatorColor = LLUIColorTable::getInstance()->getColor("ALMediaTickerOscillatorColor"); - - setPaused(true); + + if (gAudiop && gAudiop->getStreamingAudioImpl() && gAudiop->getStreamingAudioImpl()->supportsMetaData()) + { + mMetadataUpdateConnection = gAudiop->getStreamingAudioImpl()->setMetadataUpdatedCallback([this](const LLSD& metadata) { metadataUpdateCallback(metadata); }); + + metadataUpdateCallback(gAudiop->getStreamingAudioImpl()->getMetadata()); + } + else + { + metadataUpdateCallback(LLSD()); + } return LLPanel::postBuild(); } @@ -83,45 +100,34 @@ void ALPanelMusicTicker::reshape(S32 width, S32 height, BOOL called_from_parent/ void ALPanelMusicTicker::updateTickerText() //called via draw. { - if(!gAudiop) - return; + iterateTickerOffset(); +} - bool stream_paused = gAudiop->getStreamingAudioImpl()->isPlaying() != 1; //will return 1 if playing. +void ALPanelMusicTicker::metadataUpdateCallback(const LLSD& metadata) +{ + bool stream_paused = true; + + if (gAudiop && gAudiop->getStreamingAudioImpl()) + { + stream_paused = gAudiop->getStreamingAudioImpl()->isPlaying() != 1; //will return 1 if playing. + } bool dirty = setPaused(stream_paused); - if(!stream_paused) + if (!stream_paused) { - if (dirty || gAudiop->getStreamingAudioImpl()->hasNewMetaData()) - { - const LLSD* metadata = gAudiop->getStreamingAudioImpl()->getMetaData(); - LLSD artist = metadata ? metadata->get("ARTIST") : LLSD(); - LLSD title = metadata ? metadata->get("TITLE") : LLSD(); - - dirty |= setArtist(artist.isDefined() ? artist.asString() : mszLoading); - dirty |= setTitle(title.isDefined() ? title.asString() : mszLoading); - if(artist.isDefined() && title.isDefined()) - mLoadTimer.stop(); - else if(dirty) - mLoadTimer.start(); - else if(mLoadTimer.getStarted() && mLoadTimer.getElapsedTimeF64() > 10.f) //It has been 10 seconds.. give up. - { - if(!artist.isDefined()) - dirty |= setArtist(LLStringUtil::null); - if(!title.isDefined()) - dirty |= setTitle(LLStringUtil::null); - mLoadTimer.stop(); - } - } + LLSD artist = metadata["ARTIST"]; + LLSD title = metadata["TITLE"]; + + dirty |= setArtist(artist.isDefined() ? artist.asString() : LLStringUtil::null); + dirty |= setTitle(title.isDefined() ? title.asString() : LLStringUtil::null); } - if(dirty) + if (dirty) resetTicker(); - else - iterateTickerOffset(); } void ALPanelMusicTicker::drawOscilloscope() //called via draw. { - if(!gAudiop || !mVisualizer || !gAudiop->getStreamingAudioImpl()->supportsWaveData()) + if(!gAudiop || !mVisualizer || !gAudiop->getStreamingAudioImpl() || !gAudiop->getStreamingAudioImpl()->supportsWaveData()) return; static const S32 NUM_LINE_STRIPS = 64; //How many lines to draw. 64 is more than enough. diff --git a/indra/newview/alpanelmusicticker.h b/indra/newview/alpanelmusicticker.h index 6e3168330db4d2a4e9a34a237b76116c42910092..61f9519e810de69764ab15891922b7894adc26f8 100644 --- a/indra/newview/alpanelmusicticker.h +++ b/indra/newview/alpanelmusicticker.h @@ -30,6 +30,7 @@ class ALPanelMusicTicker final : public LLPanel { public: ALPanelMusicTicker(); //ctor + ~ALPanelMusicTicker(); BOOL postBuild() final override; void draw() final override; @@ -44,6 +45,8 @@ class ALPanelMusicTicker final : public LLPanel S32 countExtraChars(LLTextBox *texbox, const std::string &text); //calculates how many characters are truncated by bounds. void iterateTickerOffset(); //Logic that actually shuffles the text to the left. + void metadataUpdateCallback(const LLSD&); + enum ePlayState { STATE_PAUSED, @@ -67,6 +70,8 @@ class ALPanelMusicTicker final : public LLPanel LLTextBox* mArtistText; LLTextBox* mTitleText; LLUICtrl* mVisualizer; + + boost::signals2::connection mMetadataUpdateConnection; }; #endif // AL_PANELMUSICTICKER_H diff --git a/indra/newview/llviewermedia_streamingaudio.h b/indra/newview/llviewermedia_streamingaudio.h index 830d36b3c308fd3556100d8d0f8dcf884ccb690b..6fb1c575fd6824fa9da3e71a8db7d534dd634084 100644 --- a/indra/newview/llviewermedia_streamingaudio.h +++ b/indra/newview/llviewermedia_streamingaudio.h @@ -54,8 +54,6 @@ class LLStreamingAudio_MediaPlugins final : public LLStreamingAudioInterface void setBufferSizes(U32 streambuffertime, U32 decodebuffertime) override {}; virtual bool supportsMetaData() override { return false; } - virtual const LLSD *getMetaData() override { return nullptr; } - virtual bool hasNewMetaData() override { return false; } virtual bool supportsWaveData() override { return false; } virtual bool getWaveData(float* arr, S32 count, S32 stride = 1) override { return false; } diff --git a/indra/newview/skins/default/xui/en/floater_music_ticker.xml b/indra/newview/skins/default/xui/en/floater_music_ticker.xml index 99daa03b410cf2de60ff6df31d945ae8b6f0487e..991c2d83c7d716def65a309616d8f2f50bd42cc8 100644 --- a/indra/newview/skins/default/xui/en/floater_music_ticker.xml +++ b/indra/newview/skins/default/xui/en/floater_music_ticker.xml @@ -1,10 +1,10 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <floater - width="320" - height="39" + width="360" + height="46" layout="topleft" - min_width="300" - min_height="39" + min_width="280" + min_height="46" name="floater_music_ticker" positioning="cascading" title="" @@ -21,7 +21,7 @@ filename="panel_music_ticker.xml" layout="topleft" follows="all" - width="296" + width="336" top="0" mouse_opaque="false"/> </floater> diff --git a/indra/newview/skins/default/xui/en/panel_music_ticker.xml b/indra/newview/skins/default/xui/en/panel_music_ticker.xml index 4c380ec932d7fed3471ced17c1b5ff5ca91b6ad2..033b8b1f0f380e88d0781b8f63991c6ab465fb17 100644 --- a/indra/newview/skins/default/xui/en/panel_music_ticker.xml +++ b/indra/newview/skins/default/xui/en/panel_music_ticker.xml @@ -3,7 +3,7 @@ layout="topleft" follows="top|right|left" width="300" - height="38" + height="46" name="music_ticker"> <string name="paused"> (not playing) @@ -12,7 +12,7 @@ (loading...) </string> <icon - top="19" + top="23" color="AlAshGrey" follows="left|top|right" height="1" @@ -47,9 +47,9 @@ bg_visible="false" border_visible="false" layout="topleft" - top="0" + top="2" follows="top|left" - font="SansSerifBold" + font="SansSerifBoldLarge" h_pad="0" halign="left" height="16" @@ -64,13 +64,13 @@ bg_visible="false" border_visible="false" layout="topleft" - top="0" + top="2" follows="top|left|right" - font="SansSerifBold" + font="SansSerifLarge" h_pad="0" halign="left" height="16" - left="50" + left="56" mouse_opaque="false" name="artist_text" v_pad="0" @@ -81,9 +81,9 @@ bg_visible="false" border_visible="false" layout="topleft" - top="19" + top="26" follows="top|left" - font="SansSerifBold" + font="SansSerifBoldLarge" h_pad="0" halign="left" height="16" @@ -98,9 +98,9 @@ bg_visible="false" border_visible="false" layout="topleft" - top="19" + top="26" follows="top|left|right" - font="SansSerifBold" + font="SansSerifLarge" h_pad="0" halign="left" height="16" @@ -109,5 +109,6 @@ name="title_text" v_pad="0" width="193"> + Cummies </text> </panel>