From 192aee0f191e6070b91be066b599b8dc3302a5e1 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 31 Jan 2020 15:05:51 +0000 Subject: Merged in SL-11445 Upgrade Fmodex to Fmod Studio --- indra/llaudio/llaudioengine_fmodstudio.cpp | 659 +++++++++++++++++++++++++++++ 1 file changed, 659 insertions(+) create mode 100644 indra/llaudio/llaudioengine_fmodstudio.cpp (limited to 'indra/llaudio/llaudioengine_fmodstudio.cpp') diff --git a/indra/llaudio/llaudioengine_fmodstudio.cpp b/indra/llaudio/llaudioengine_fmodstudio.cpp new file mode 100644 index 0000000000..ec66d590b7 --- /dev/null +++ b/indra/llaudio/llaudioengine_fmodstudio.cpp @@ -0,0 +1,659 @@ +/** + * @file audioengine_fmodstudio.cpp + * @brief Implementation of LLAudioEngine class abstracting the audio + * support as a FMODSTUDIO implementation + * + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2020, 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$ + */ + +#include "linden_common.h" + +#include "llstreamingaudio.h" +#include "llstreamingaudio_fmodstudio.h" + +#include "llaudioengine_fmodstudio.h" +#include "lllistener_fmodstudio.h" + +#include "llerror.h" +#include "llmath.h" +#include "llrand.h" + +#include "fmodstudio/fmod.hpp" +#include "fmodstudio/fmod_errors.h" +#include "lldir.h" +#include "llapr.h" + +#include "sound_ids.h" + +FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels); + +FMOD::ChannelGroup *LLAudioEngine_FMODSTUDIO::mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT] = {0}; + +LLAudioEngine_FMODSTUDIO::LLAudioEngine_FMODSTUDIO(bool enable_profiler) +{ + mInited = false; + mWindGen = NULL; + mWindDSP = NULL; + mSystem = NULL; + mEnableProfiler = enable_profiler; + mWindDSPDesc = new FMOD_DSP_DESCRIPTION(); +} + + +LLAudioEngine_FMODSTUDIO::~LLAudioEngine_FMODSTUDIO() +{ + delete mWindDSPDesc; +} + + +static inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string) +{ + if (result == FMOD_OK) + return false; + LL_DEBUGS() << string << " Error: " << FMOD_ErrorString(result) << LL_ENDL; + return true; +} + +bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata) +{ + U32 version; + FMOD_RESULT result; + + LL_DEBUGS("AppInit") << "LLAudioEngine_FMODSTUDIO::init() initializing FMOD" << LL_ENDL; + + result = FMOD::System_Create(&mSystem); + if (Check_FMOD_Error(result, "FMOD::System_Create")) + return false; + + //will call LLAudioEngine_FMODSTUDIO::allocateListener, which needs a valid mSystem pointer. + LLAudioEngine::init(num_channels, userdata); + + result = mSystem->getVersion(&version); + Check_FMOD_Error(result, "FMOD::System::getVersion"); + + if (version < FMOD_VERSION) + { + LL_WARNS("AppInit") << "FMOD Studio version mismatch, actual: " << version + << " expected:" << FMOD_VERSION << LL_ENDL; + } + + // In this case, all sounds, PLUS wind and stream will be software. + result = mSystem->setSoftwareChannels(num_channels + 2); + Check_FMOD_Error(result, "FMOD::System::setSoftwareChannels"); + + FMOD_ADVANCEDSETTINGS settings; + memset(&settings, 0, sizeof(settings)); + settings.cbSize = sizeof(FMOD_ADVANCEDSETTINGS); + settings.resamplerMethod = FMOD_DSP_RESAMPLER_LINEAR; + + result = mSystem->setAdvancedSettings(&settings); + Check_FMOD_Error(result, "FMOD::System::setAdvancedSettings"); + + U32 fmod_flags = FMOD_INIT_NORMAL | FMOD_INIT_3D_RIGHTHANDED | FMOD_INIT_THREAD_UNSAFE; + if (mEnableProfiler) + { + fmod_flags |= FMOD_INIT_PROFILE_ENABLE; + } + + // initialize the FMOD engine + // number of channel in this case looks to be identiacal to number of max simultaneously + // playing objects and we can set practically any number + result = mSystem->init(num_channels + 2, fmod_flags, 0); + if (Check_FMOD_Error(result, "Error initializing FMOD Studio")) + { + // If it fails here and (result == FMOD_ERR_OUTPUT_CREATEBUFFER), + // we can retry with other settings + return false; + } + + // set up our favourite FMOD-native streaming audio implementation if none has already been added + if (!getStreamingAudioImpl()) // no existing implementation added + setStreamingAudioImpl(new LLStreamingAudio_FMODSTUDIO(mSystem)); + + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init() FMOD Studio initialized correctly" << LL_ENDL; + + int r_numbuffers, r_samplerate, r_channels; + unsigned int r_bufferlength; + char r_name[512]; + int latency = 100; + mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers); + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): r_bufferlength=" << r_bufferlength << " bytes" << LL_ENDL; + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): r_numbuffers=" << r_numbuffers << LL_ENDL; + + mSystem->getDriverInfo(0, r_name, 511, NULL, &r_samplerate, NULL, &r_channels); + r_name[511] = '\0'; + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): r_name=\"" << r_name << "\"" << LL_ENDL; + + if (r_samplerate != 0) + latency = (int)(1000.0f * r_bufferlength * r_numbuffers / r_samplerate); + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): latency=" << latency << "ms" << LL_ENDL; + + mInited = true; + + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): initialization complete." << LL_ENDL; + + return true; +} + + +std::string LLAudioEngine_FMODSTUDIO::getDriverName(bool verbose) +{ + llassert_always(mSystem); + if (verbose) + { + U32 version; + if (!Check_FMOD_Error(mSystem->getVersion(&version), "FMOD::System::getVersion")) + { + return llformat("FMOD Studio %1x.%02x.%02x", version >> 16, version >> 8 & 0x000000FF, version & 0x000000FF); + } + } + return "FMODSTUDIO"; +} + + +void LLAudioEngine_FMODSTUDIO::allocateListener(void) +{ + mListenerp = (LLListener *) new LLListener_FMODSTUDIO(mSystem); + if (!mListenerp) + { + LL_WARNS() << "Listener creation failed" << LL_ENDL; + } +} + + +void LLAudioEngine_FMODSTUDIO::shutdown() +{ + stopInternetStream(); + + LL_INFOS() << "About to LLAudioEngine::shutdown()" << LL_ENDL; + LLAudioEngine::shutdown(); + + LL_INFOS() << "LLAudioEngine_FMODSTUDIO::shutdown() closing FMOD Studio" << LL_ENDL; + if (mSystem) + { + mSystem->close(); + mSystem->release(); + } + LL_INFOS() << "LLAudioEngine_FMODSTUDIO::shutdown() done closing FMOD Studio" << LL_ENDL; + + delete mListenerp; + mListenerp = NULL; +} + + +LLAudioBuffer * LLAudioEngine_FMODSTUDIO::createBuffer() +{ + return new LLAudioBufferFMODSTUDIO(mSystem); +} + + +LLAudioChannel * LLAudioEngine_FMODSTUDIO::createChannel() +{ + return new LLAudioChannelFMODSTUDIO(mSystem); +} + +bool LLAudioEngine_FMODSTUDIO::initWind() +{ + mNextWindUpdate = 0.0; + + if (!mWindDSP) + { + memset(mWindDSPDesc, 0, sizeof(*mWindDSPDesc)); //Set everything to zero + strncpy(mWindDSPDesc->name, "Wind Unit", sizeof(mWindDSPDesc->name)); + mWindDSPDesc->pluginsdkversion = FMOD_PLUGIN_SDK_VERSION; + mWindDSPDesc->read = &windCallback; // Assign callback - may be called from arbitrary threads + if (Check_FMOD_Error(mSystem->createDSP(mWindDSPDesc, &mWindDSP), "FMOD::createDSP")) + return false; + + if (mWindGen) + delete mWindGen; + + int frequency = 44100; + + FMOD_SPEAKERMODE mode; + if (Check_FMOD_Error(mSystem->getSoftwareFormat(&frequency, &mode, nullptr), "FMOD::System::getSoftwareFormat")) + { + cleanupWind(); + return false; + } + + mWindGen = new LLWindGen((U32)frequency); + + if (Check_FMOD_Error(mWindDSP->setUserData((void*)mWindGen), "FMOD::DSP::setUserData")) + { + cleanupWind(); + return false; + } + if (Check_FMOD_Error(mWindDSP->setChannelFormat(FMOD_CHANNELMASK_STEREO, 2, mode), "FMOD::DSP::setChannelFormat")) + { + cleanupWind(); + return false; + } + } + + // *TODO: Should this guard against multiple plays? + if (Check_FMOD_Error(mSystem->playDSP(mWindDSP, nullptr, false, nullptr), "FMOD::System::playDSP")) + { + cleanupWind(); + return false; + } + return true; +} + + +void LLAudioEngine_FMODSTUDIO::cleanupWind() +{ + if (mWindDSP) + { + FMOD::ChannelGroup* master_group = NULL; + if (!Check_FMOD_Error(mSystem->getMasterChannelGroup(&master_group), "FMOD::System::getMasterChannelGroup") + && master_group) + { + master_group->removeDSP(mWindDSP); + } + mWindDSP->release(); + mWindDSP = NULL; + } + + delete mWindDSPDesc; + mWindDSPDesc = NULL; + + delete mWindGen; + mWindGen = NULL; +} + + +//----------------------------------------------------------------------- +void LLAudioEngine_FMODSTUDIO::updateWind(LLVector3 wind_vec, F32 camera_height_above_water) +{ + LLVector3 wind_pos; + F64 pitch; + F64 center_freq; + + if (!mEnableWind) + { + return; + } + + if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL)) + { + + // wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up) + // need to convert this to the conventional orientation DS3D and OpenAL use + // where +X = right, +Y = up, +Z = backwards + + wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]); + + // cerr << "Wind update" << endl; + + pitch = 1.0 + mapWindVecToPitch(wind_vec); + center_freq = 80.0 * pow(pitch, 2.5*(mapWindVecToGain(wind_vec) + 1.0)); + + mWindGen->mTargetFreq = (F32)center_freq; + mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain; + mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec); + } +} + +//----------------------------------------------------------------------- +void LLAudioEngine_FMODSTUDIO::setInternalGain(F32 gain) +{ + if (!mInited) + { + return; + } + + gain = llclamp(gain, 0.0f, 1.0f); + + FMOD::ChannelGroup *master_group; + mSystem->getMasterChannelGroup(&master_group); + + master_group->setVolume(gain); + + LLStreamingAudioInterface *saimpl = getStreamingAudioImpl(); + if (saimpl) + { + // fmod likes its streaming audio channel gain re-asserted after + // master volume change. + saimpl->setGain(saimpl->getGain()); + } +} + +// +// LLAudioChannelFMODSTUDIO implementation +// + +LLAudioChannelFMODSTUDIO::LLAudioChannelFMODSTUDIO(FMOD::System *system) : LLAudioChannel(), mSystemp(system), mChannelp(NULL), mLastSamplePos(0) +{ +} + + +LLAudioChannelFMODSTUDIO::~LLAudioChannelFMODSTUDIO() +{ + cleanup(); +} + +bool LLAudioChannelFMODSTUDIO::updateBuffer() +{ + if (LLAudioChannel::updateBuffer()) + { + // Base class update returned true, which means that we need to actually + // set up the channel for a different buffer. + + LLAudioBufferFMODSTUDIO *bufferp = (LLAudioBufferFMODSTUDIO *)mCurrentSourcep->getCurrentBuffer(); + + // Grab the FMOD sample associated with the buffer + FMOD::Sound *soundp = bufferp->getSound(); + if (!soundp) + { + // This is bad, there should ALWAYS be a sound associated with a legit + // buffer. + LL_ERRS() << "No FMOD sound!" << LL_ENDL; + return false; + } + + + // Actually play the sound. Start it off paused so we can do all the necessary + // setup. + if (!mChannelp) + { + FMOD_RESULT result = getSystem()->playSound(soundp, NULL /*free channel?*/, true, &mChannelp); + Check_FMOD_Error(result, "FMOD::System::playSound"); + } + + // Setting up channel mChannelID + } + + // If we have a source for the channel, we need to update its gain. + if (mCurrentSourcep) + { + // SJB: warnings can spam and hurt framerate, disabling + //FMOD_RESULT result; + + mChannelp->setVolume(getSecondaryGain() * mCurrentSourcep->getGain()); + //Check_FMOD_Error(result, "FMOD::Channel::setVolume"); + + mChannelp->setMode(mCurrentSourcep->isLoop() ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF); + /*if(Check_FMOD_Error(result, "FMOD::Channel::setMode")) + { + S32 index; + mChannelp->getIndex(&index); + LL_WARNS() << "Channel " << index << "Source ID: " << mCurrentSourcep->getID() + << " at " << mCurrentSourcep->getPositionGlobal() << LL_ENDL; + }*/ + } + + return true; +} + + +void LLAudioChannelFMODSTUDIO::update3DPosition() +{ + if (!mChannelp) + { + // We're not actually a live channel (i.e., we're not playing back anything) + return; + } + + LLAudioBufferFMODSTUDIO *bufferp = (LLAudioBufferFMODSTUDIO *)mCurrentBufferp; + if (!bufferp) + { + // We don't have a buffer associated with us (should really have been picked up + // by the above if. + return; + } + + if (mCurrentSourcep->isAmbient()) + { + // Ambient sound, don't need to do any positional updates. + set3DMode(false); + } + else + { + // Localized sound. Update the position and velocity of the sound. + set3DMode(true); + + LLVector3 float_pos; + float_pos.setVec(mCurrentSourcep->getPositionGlobal()); + FMOD_RESULT result = mChannelp->set3DAttributes((FMOD_VECTOR*)float_pos.mV, (FMOD_VECTOR*)mCurrentSourcep->getVelocity().mV); + Check_FMOD_Error(result, "FMOD::Channel::set3DAttributes"); + } +} + + +void LLAudioChannelFMODSTUDIO::updateLoop() +{ + if (!mChannelp) + { + // May want to clear up the loop/sample counters. + return; + } + + // + // Hack: We keep track of whether we looped or not by seeing when the + // sample position looks like it's going backwards. Not reliable; may + // yield false negatives. + // + U32 cur_pos; + mChannelp->getPosition(&cur_pos, FMOD_TIMEUNIT_PCMBYTES); + + if (cur_pos < (U32)mLastSamplePos) + { + mLoopedThisFrame = true; + } + mLastSamplePos = cur_pos; +} + + +void LLAudioChannelFMODSTUDIO::cleanup() +{ + if (!mChannelp) + { + // Aborting cleanup with no channel handle. + return; + } + + //Cleaning up channel mChannelID + Check_FMOD_Error(mChannelp->stop(), "FMOD::Channel::stop"); + + mCurrentBufferp = NULL; + mChannelp = NULL; +} + + +void LLAudioChannelFMODSTUDIO::play() +{ + if (!mChannelp) + { + LL_WARNS() << "Playing without a channel handle, aborting" << LL_ENDL; + return; + } + + Check_FMOD_Error(mChannelp->setPaused(false), "FMOD::Channel::pause"); + + getSource()->setPlayedOnce(true); + + if (LLAudioEngine_FMODSTUDIO::mChannelGroups[getSource()->getType()]) + mChannelp->setChannelGroup(LLAudioEngine_FMODSTUDIO::mChannelGroups[getSource()->getType()]); +} + + +void LLAudioChannelFMODSTUDIO::playSynced(LLAudioChannel *channelp) +{ + LLAudioChannelFMODSTUDIO *fmod_channelp = (LLAudioChannelFMODSTUDIO*)channelp; + if (!(fmod_channelp->mChannelp && mChannelp)) + { + // Don't have channels allocated to both the master and the slave + return; + } + + U32 cur_pos; + if (Check_FMOD_Error(mChannelp->getPosition(&cur_pos, FMOD_TIMEUNIT_PCMBYTES), "Unable to retrieve current position")) + return; + + cur_pos %= mCurrentBufferp->getLength(); + + // Try to match the position of our sync master + Check_FMOD_Error(mChannelp->setPosition(cur_pos, FMOD_TIMEUNIT_PCMBYTES), "Unable to set current position"); + + // Start us playing + play(); +} + + +bool LLAudioChannelFMODSTUDIO::isPlaying() +{ + if (!mChannelp) + { + return false; + } + + bool paused, playing; + mChannelp->getPaused(&paused); + mChannelp->isPlaying(&playing); + return !paused && playing; +} + + +// +// LLAudioChannelFMODSTUDIO implementation +// + + +LLAudioBufferFMODSTUDIO::LLAudioBufferFMODSTUDIO(FMOD::System *system) : mSystemp(system), mSoundp(NULL) +{ +} + + +LLAudioBufferFMODSTUDIO::~LLAudioBufferFMODSTUDIO() +{ + if (mSoundp) + { + mSoundp->release(); + mSoundp = NULL; + } +} + + +bool LLAudioBufferFMODSTUDIO::loadWAV(const std::string& filename) +{ + // Try to open a wav file from disk. This will eventually go away, as we don't + // really want to block doing this. + if (filename.empty()) + { + // invalid filename, abort. + return false; + } + + if (!LLAPRFile::isExist(filename, NULL, LL_APR_RPB)) + { + // File not found, abort. + return false; + } + + if (mSoundp) + { + // If there's already something loaded in this buffer, clean it up. + mSoundp->release(); + mSoundp = NULL; + } + + FMOD_MODE base_mode = FMOD_LOOP_NORMAL; + FMOD_CREATESOUNDEXINFO exinfo; + memset(&exinfo, 0, sizeof(exinfo)); + exinfo.cbsize = sizeof(exinfo); + exinfo.suggestedsoundtype = FMOD_SOUND_TYPE_WAV; //Hint to speed up loading. + // Load up the wav file into an fmod sample +#if LL_WINDOWS + FMOD_RESULT result = getSystem()->createSound((const char*)utf8str_to_utf16str(filename).c_str(), base_mode, &exinfo, &mSoundp); +#else + FMOD_RESULT result = getSystem()->createSound(filename.c_str(), base_mode, &exinfo, &mSoundp); +#endif + + if (result != FMOD_OK) + { + // We failed to load the file for some reason. + LL_WARNS() << "Could not load data '" << filename << "': " << FMOD_ErrorString(result) << LL_ENDL; + + // + // If we EVER want to load wav files provided by end users, we need + // to rethink this! + // + // file is probably corrupt - remove it. + LLFile::remove(filename); + return false; + } + + // Everything went well, return true + return true; +} + + +U32 LLAudioBufferFMODSTUDIO::getLength() +{ + if (!mSoundp) + { + return 0; + } + + U32 length; + mSoundp->getLength(&length, FMOD_TIMEUNIT_PCMBYTES); + return length; +} + + +void LLAudioChannelFMODSTUDIO::set3DMode(bool use3d) +{ + FMOD_MODE current_mode; + if (mChannelp->getMode(¤t_mode) != FMOD_OK) + return; + FMOD_MODE new_mode = current_mode; + new_mode &= ~(use3d ? FMOD_2D : FMOD_3D); + new_mode |= use3d ? FMOD_3D : FMOD_2D; + + if (current_mode != new_mode) + { + mChannelp->setMode(new_mode); + } +} + +// *NOTE: This is almost certainly being called on the mixer thread, +// not the main thread. May have implications for callees or audio +// engine shutdown. + +FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels) +{ + // inbuffer = fmod's original mixbuffer. + // outbuffer = the buffer passed from the previous DSP unit. + // length = length in samples at this mix time. + + LLWindGen *windgen; + FMOD::DSP *thisdsp = (FMOD::DSP *)dsp_state->instance; + + thisdsp->getUserData((void **)&windgen); + S32 channels, configwidth, configheight; + thisdsp->getInfo(0, 0, &channels, &configwidth, &configheight); + + windgen->windGenerate((LLAudioEngine_FMODSTUDIO::MIXBUFFERFORMAT *)outbuffer, length); + + return FMOD_OK; +} -- cgit v1.3 From 9a6dcc011c54f65e5da3c3b92074386946d8f291 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 5 Feb 2020 00:58:37 +0200 Subject: SL-11455 Added linux pulseaudio and alsa support --- indra/llaudio/llaudioengine_fmodstudio.cpp | 71 +++++++++++++++++++++++++++++ indra/newview/linux_tools/client-readme.txt | 2 +- indra/newview/linux_tools/wrapper.sh | 8 +--- 3 files changed, 74 insertions(+), 7 deletions(-) (limited to 'indra/llaudio/llaudioengine_fmodstudio.cpp') diff --git a/indra/llaudio/llaudioengine_fmodstudio.cpp b/indra/llaudio/llaudioengine_fmodstudio.cpp index ec66d590b7..1dd9b830a6 100644 --- a/indra/llaudio/llaudioengine_fmodstudio.cpp +++ b/indra/llaudio/llaudioengine_fmodstudio.cpp @@ -114,6 +114,76 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata) fmod_flags |= FMOD_INIT_PROFILE_ENABLE; } +#if LL_LINUX + bool audio_ok = false; + + if (!audio_ok) + { + const char* env_string = getenv("LL_BAD_FMOD_PULSEAUDIO"); + if (NULL == env_string) + { + LL_DEBUGS("AppInit") << "Trying PulseAudio audio output..." << LL_ENDL; + if (mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO) == FMOD_OK && + (result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK) + { + LL_DEBUGS("AppInit") << "PulseAudio output initialized OKAY" << LL_ENDL; + audio_ok = true; + } + else + { + Check_FMOD_Error(result, "PulseAudio audio output FAILED to initialize"); + } + } + else + { + LL_DEBUGS("AppInit") << "PulseAudio audio output SKIPPED" << LL_ENDL; + } + } + if (!audio_ok) + { + const char* env_string = getenv("LL_BAD_FMOD_ALSA"); + if (NULL == env_string) + { + LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL; + if (mSystem->setOutput(FMOD_OUTPUTTYPE_ALSA) == FMOD_OK && + (result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK) + { + LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL; + audio_ok = true; + } + else + { + Check_FMOD_Error(result, "ALSA audio output FAILED to initialize"); + } + } + else + { + LL_DEBUGS("AppInit") << "ALSA audio output SKIPPED" << LL_ENDL; + } + } + if (!audio_ok) + { + LL_WARNS("AppInit") << "Overall audio init failure." << LL_ENDL; + return false; + } + + // We're interested in logging which output method we + // ended up with, for QA purposes. + FMOD_OUTPUTTYPE output_type; + mSystem->getOutput(&output_type); + switch (output_type) + { + case FMOD_OUTPUTTYPE_NOSOUND: + LL_INFOS("AppInit") << "Audio output: NoSound" << LL_ENDL; break; + case FMOD_OUTPUTTYPE_PULSEAUDIO: + LL_INFOS("AppInit") << "Audio output: PulseAudio" << LL_ENDL; break; + case FMOD_OUTPUTTYPE_ALSA: + LL_INFOS("AppInit") << "Audio output: ALSA" << LL_ENDL; break; + default: + LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break; + }; +#else // LL_LINUX + // initialize the FMOD engine // number of channel in this case looks to be identiacal to number of max simultaneously // playing objects and we can set practically any number @@ -124,6 +194,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata) // we can retry with other settings return false; } +#endif // set up our favourite FMOD-native streaming audio implementation if none has already been added if (!getStreamingAudioImpl()) // no existing implementation added diff --git a/indra/newview/linux_tools/client-readme.txt b/indra/newview/linux_tools/client-readme.txt index aaa8a6b6d7..cb8d1af535 100644 --- a/indra/newview/linux_tools/client-readme.txt +++ b/indra/newview/linux_tools/client-readme.txt @@ -188,7 +188,7 @@ configuration options for advanced troubleshooters. * AUDIO - Edit the 'secondlife' script and you will see these audio options: LL_BAD_OPENAL_DRIVER, LL_BAD_FMODSTUDIO_DRIVER. - Second Life tries to use OpenAL, FMODSTUDIO + Second Life tries to use OpenAL, FMODSTUDIO (PULSEAUDIO, ALSA) audio drivers in this order; you may uncomment the corresponding LL_BAD_* option to skip an audio driver which you believe may be causing you trouble. diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index e04090297c..eb3ead433b 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -6,17 +6,13 @@ ## - Avoids using any FMOD STUDIO audio driver. #export LL_BAD_FMODSTUDIO_DRIVER=x -## - Avoids using any FMOD Ex audio driver. -#export LL_BAD_FMODEX_DRIVER=x ## - Avoids using any OpenAL audio driver. #export LL_BAD_OPENAL_DRIVER=x -## - Avoids using the FMOD Ex PulseAudio audio driver. +## - Avoids using the FMOD Studio or FMOD Ex PulseAudio audio driver. #export LL_BAD_FMOD_PULSEAUDIO=x -## - Avoids using the FMOD or FMOD Ex ALSA audio driver. +## - Avoids using the FMOD Studio or FMOD Ex ALSA audio driver. #export LL_BAD_FMOD_ALSA=x -## - Avoids using the FMOD or FMOD Ex OSS audio driver. -#export LL_BAD_FMOD_OSS=x ## - Avoids the optional OpenGL extensions which have proven most problematic ## on some hardware. Disabling this option may cause BETTER PERFORMANCE but -- cgit v1.3 From f5ec281b1b578dfee17353ecf6d469a29de86d25 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 19 Mar 2020 15:47:49 +0200 Subject: SL-11445 Fix crash caused by wind cleanup --- indra/llaudio/llaudioengine_fmodstudio.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'indra/llaudio/llaudioengine_fmodstudio.cpp') diff --git a/indra/llaudio/llaudioengine_fmodstudio.cpp b/indra/llaudio/llaudioengine_fmodstudio.cpp index 1dd9b830a6..15bf8926c1 100644 --- a/indra/llaudio/llaudioengine_fmodstudio.cpp +++ b/indra/llaudio/llaudioengine_fmodstudio.cpp @@ -55,7 +55,7 @@ LLAudioEngine_FMODSTUDIO::LLAudioEngine_FMODSTUDIO(bool enable_profiler) mWindDSP = NULL; mSystem = NULL; mEnableProfiler = enable_profiler; - mWindDSPDesc = new FMOD_DSP_DESCRIPTION(); + mWindDSPDesc = NULL; } @@ -286,6 +286,11 @@ bool LLAudioEngine_FMODSTUDIO::initWind() { mNextWindUpdate = 0.0; + if (!mWindDSPDesc) + { + mWindDSPDesc = new FMOD_DSP_DESCRIPTION(); + } + if (!mWindDSP) { memset(mWindDSPDesc, 0, sizeof(*mWindDSPDesc)); //Set everything to zero -- cgit v1.3 From 8cb9bcf1d6379afb3f0784c3741f77b5df437dea Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 9 Apr 2020 13:12:30 +0300 Subject: SL-11445 Fix fmod studio opening audio files --- indra/llaudio/llaudioengine_fmodstudio.cpp | 31 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 16 deletions(-) (limited to 'indra/llaudio/llaudioengine_fmodstudio.cpp') diff --git a/indra/llaudio/llaudioengine_fmodstudio.cpp b/indra/llaudio/llaudioengine_fmodstudio.cpp index 15bf8926c1..8f07c81c57 100644 --- a/indra/llaudio/llaudioengine_fmodstudio.cpp +++ b/indra/llaudio/llaudioengine_fmodstudio.cpp @@ -49,19 +49,20 @@ FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, FMOD::ChannelGroup *LLAudioEngine_FMODSTUDIO::mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT] = {0}; LLAudioEngine_FMODSTUDIO::LLAudioEngine_FMODSTUDIO(bool enable_profiler) +: mInited(false), + mWindGen(NULL), + mWindDSP(NULL), + mSystem(NULL), + mEnableProfiler(enable_profiler), + mWindDSPDesc(NULL) { - mInited = false; - mWindGen = NULL; - mWindDSP = NULL; - mSystem = NULL; - mEnableProfiler = enable_profiler; - mWindDSPDesc = NULL; } LLAudioEngine_FMODSTUDIO::~LLAudioEngine_FMODSTUDIO() { - delete mWindDSPDesc; + // mWindDSPDesc, mWindGen and mWindDSP get cleaned up on cleanupWind in LLAudioEngine::shutdown() + // mSystem gets cleaned up at shutdown() } @@ -400,10 +401,12 @@ void LLAudioEngine_FMODSTUDIO::setInternalGain(F32 gain) gain = llclamp(gain, 0.0f, 1.0f); - FMOD::ChannelGroup *master_group; - mSystem->getMasterChannelGroup(&master_group); - - master_group->setVolume(gain); + FMOD::ChannelGroup* master_group = NULL; + if (!Check_FMOD_Error(mSystem->getMasterChannelGroup(&master_group), "FMOD::System::getMasterChannelGroup") + && master_group) + { + master_group->setVolume(gain); + } LLStreamingAudioInterface *saimpl = getStreamingAudioImpl(); if (saimpl) @@ -658,12 +661,8 @@ bool LLAudioBufferFMODSTUDIO::loadWAV(const std::string& filename) memset(&exinfo, 0, sizeof(exinfo)); exinfo.cbsize = sizeof(exinfo); exinfo.suggestedsoundtype = FMOD_SOUND_TYPE_WAV; //Hint to speed up loading. - // Load up the wav file into an fmod sample -#if LL_WINDOWS - FMOD_RESULT result = getSystem()->createSound((const char*)utf8str_to_utf16str(filename).c_str(), base_mode, &exinfo, &mSoundp); -#else + // Load up the wav file into an fmod sample (since 1.05 fmod studio expects everything in UTF-8) FMOD_RESULT result = getSystem()->createSound(filename.c_str(), base_mode, &exinfo, &mSoundp); -#endif if (result != FMOD_OK) { -- cgit v1.3 From c0ce2565918af03f1dabcb02dedb87c1c447008a Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 9 Apr 2020 16:04:37 +0300 Subject: SL-11445 Fix fmod studio position and orientation attributes --- indra/llaudio/llaudioengine_fmodstudio.cpp | 2 -- indra/llaudio/lllistener_fmodstudio.cpp | 13 +++++-------- 2 files changed, 5 insertions(+), 10 deletions(-) (limited to 'indra/llaudio/llaudioengine_fmodstudio.cpp') diff --git a/indra/llaudio/llaudioengine_fmodstudio.cpp b/indra/llaudio/llaudioengine_fmodstudio.cpp index 8f07c81c57..49ae01b44d 100644 --- a/indra/llaudio/llaudioengine_fmodstudio.cpp +++ b/indra/llaudio/llaudioengine_fmodstudio.cpp @@ -725,8 +725,6 @@ FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, FMOD::DSP *thisdsp = (FMOD::DSP *)dsp_state->instance; thisdsp->getUserData((void **)&windgen); - S32 channels, configwidth, configheight; - thisdsp->getInfo(0, 0, &channels, &configwidth, &configheight); windgen->windGenerate((LLAudioEngine_FMODSTUDIO::MIXBUFFERFORMAT *)outbuffer, length); diff --git a/indra/llaudio/lllistener_fmodstudio.cpp b/indra/llaudio/lllistener_fmodstudio.cpp index 34f3d00eae..abd5e345b5 100644 --- a/indra/llaudio/lllistener_fmodstudio.cpp +++ b/indra/llaudio/lllistener_fmodstudio.cpp @@ -82,11 +82,8 @@ void LLListener_FMODSTUDIO::orient(LLVector3 up, LLVector3 at) { LLListener::orient(up, at); - // Welcome to the transition between right and left - // (coordinate systems, that is) - // Leaving the at vector alone results in a L/R reversal - // since DX is left-handed and we (LL, OpenGL, OpenAL) are right-handed - at = -at; + // at = -at; by default Fmod studio is 'left-handed' but we are providing + // flag FMOD_INIT_3D_RIGHTHANDED so no correction are needed mSystem->set3DListenerAttributes(0, NULL, NULL, (FMOD_VECTOR*)at.mV, (FMOD_VECTOR*)up.mV); } @@ -106,14 +103,14 @@ void LLListener_FMODSTUDIO::commitDeferredChanges() void LLListener_FMODSTUDIO::setRolloffFactor(F32 factor) { //An internal FMOD optimization skips 3D updates if there have not been changes to the 3D sound environment. - // (this was true for FMODex, looks to be still true for FMOD STUDIO) + // (this was true for FMODex, looks to be still true for FMOD STUDIO, but needs a recheck) //Sadly, a change in rolloff is not accounted for, thus we must touch the listener properties as well. //In short: Changing the position ticks a dirtyflag inside fmod, which makes it not skip 3D processing next update call. if (mRolloffFactor != factor) { - LLVector3 pos = mVelocity - LLVector3(0.f, 0.f, .1f); + LLVector3 pos = mPosition - LLVector3(0.f, 0.f, .1f); mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)pos.mV, NULL, NULL, NULL); - mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mVelocity.mV, NULL, NULL, NULL); + mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, NULL, NULL); } mRolloffFactor = factor; mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor); -- cgit v1.3 From 1598a368cd56d9129ce9b9ce6819ec508f4d7253 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 9 Apr 2020 16:57:19 +0300 Subject: SL-11445 On exit LLWindGen can be invalid --- indra/llaudio/llaudioengine_fmodstudio.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'indra/llaudio/llaudioengine_fmodstudio.cpp') diff --git a/indra/llaudio/llaudioengine_fmodstudio.cpp b/indra/llaudio/llaudioengine_fmodstudio.cpp index 49ae01b44d..32d2266fdb 100644 --- a/indra/llaudio/llaudioengine_fmodstudio.cpp +++ b/indra/llaudio/llaudioengine_fmodstudio.cpp @@ -721,12 +721,15 @@ FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, // outbuffer = the buffer passed from the previous DSP unit. // length = length in samples at this mix time. - LLWindGen *windgen; + LLWindGen *windgen = NULL; FMOD::DSP *thisdsp = (FMOD::DSP *)dsp_state->instance; thisdsp->getUserData((void **)&windgen); - windgen->windGenerate((LLAudioEngine_FMODSTUDIO::MIXBUFFERFORMAT *)outbuffer, length); + if (windgen) + { + windgen->windGenerate((LLAudioEngine_FMODSTUDIO::MIXBUFFERFORMAT *)outbuffer, length); + } return FMOD_OK; } -- cgit v1.3 From 2542a3ed795d3a7ac664e0ca7ec4b5d8108dfce8 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 10 Apr 2020 13:58:58 +0300 Subject: SL-11445 Provide 'name' for Pulse Audio --- indra/llaudio/llaudioengine.cpp | 2 +- indra/llaudio/llaudioengine.h | 2 +- indra/llaudio/llaudioengine_fmodstudio.cpp | 19 +++++++++++++++---- indra/llaudio/llaudioengine_fmodstudio.h | 2 +- indra/llaudio/llaudioengine_openal.cpp | 9 ++++++++- indra/llaudio/llaudioengine_openal.h | 4 ++-- indra/newview/llstartup.cpp | 2 +- 7 files changed, 29 insertions(+), 11 deletions(-) (limited to 'indra/llaudio/llaudioengine_fmodstudio.cpp') diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index f49028aad5..1d447f32ae 100644 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -111,7 +111,7 @@ void LLAudioEngine::setDefaults() } -bool LLAudioEngine::init(const S32 num_channels, void* userdata) +bool LLAudioEngine::init(const S32 num_channels, void* userdata, const std::string &app_title) { setDefaults(); diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h index f1e1b4e308..97674f15f7 100644 --- a/indra/llaudio/llaudioengine.h +++ b/indra/llaudio/llaudioengine.h @@ -99,7 +99,7 @@ public: virtual ~LLAudioEngine(); // initialization/startup/shutdown - virtual bool init(const S32 num_channels, void *userdata); + virtual bool init(const S32 num_channels, void *userdata, const std::string &app_title); virtual std::string getDriverName(bool verbose) = 0; virtual void shutdown(); diff --git a/indra/llaudio/llaudioengine_fmodstudio.cpp b/indra/llaudio/llaudioengine_fmodstudio.cpp index 32d2266fdb..06a5776eb1 100644 --- a/indra/llaudio/llaudioengine_fmodstudio.cpp +++ b/indra/llaudio/llaudioengine_fmodstudio.cpp @@ -74,7 +74,7 @@ static inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string) return true; } -bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata) +bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, const std::string &app_title) { U32 version; FMOD_RESULT result; @@ -86,7 +86,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata) return false; //will call LLAudioEngine_FMODSTUDIO::allocateListener, which needs a valid mSystem pointer. - LLAudioEngine::init(num_channels, userdata); + LLAudioEngine::init(num_channels, userdata, app_title); result = mSystem->getVersion(&version); Check_FMOD_Error(result, "FMOD::System::getVersion"); @@ -97,6 +97,8 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata) << " expected:" << FMOD_VERSION << LL_ENDL; } + // In case we need to force sampling on stereo, use setSoftwareFormat here + // In this case, all sounds, PLUS wind and stream will be software. result = mSystem->setSoftwareChannels(num_channels + 2); Check_FMOD_Error(result, "FMOD::System::setSoftwareChannels"); @@ -109,6 +111,8 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata) result = mSystem->setAdvancedSettings(&settings); Check_FMOD_Error(result, "FMOD::System::setAdvancedSettings"); + // FMOD_INIT_THREAD_UNSAFE Disables thread safety for API calls. + // Only use this if FMOD is being called from a single thread, and if Studio API is not being used. U32 fmod_flags = FMOD_INIT_NORMAL | FMOD_INIT_3D_RIGHTHANDED | FMOD_INIT_THREAD_UNSAFE; if (mEnableProfiler) { @@ -125,7 +129,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata) { LL_DEBUGS("AppInit") << "Trying PulseAudio audio output..." << LL_ENDL; if (mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO) == FMOD_OK && - (result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK) + (result = mSystem->init(num_channels + 2, fmod_flags, const_cast(app_title.c_str()))) == FMOD_OK) { LL_DEBUGS("AppInit") << "PulseAudio output initialized OKAY" << LL_ENDL; audio_ok = true; @@ -238,7 +242,7 @@ std::string LLAudioEngine_FMODSTUDIO::getDriverName(bool verbose) return llformat("FMOD Studio %1x.%02x.%02x", version >> 16, version >> 8 & 0x000000FF, version & 0x000000FF); } } - return "FMODSTUDIO"; + return "FMOD STUDIO"; } @@ -433,6 +437,13 @@ LLAudioChannelFMODSTUDIO::~LLAudioChannelFMODSTUDIO() bool LLAudioChannelFMODSTUDIO::updateBuffer() { + if (!mCurrentSourcep) + { + // This channel isn't associated with any source, nothing + // to be updated + return false; + } + if (LLAudioChannel::updateBuffer()) { // Base class update returned true, which means that we need to actually diff --git a/indra/llaudio/llaudioengine_fmodstudio.h b/indra/llaudio/llaudioengine_fmodstudio.h index 69276244da..f2361df1b6 100644 --- a/indra/llaudio/llaudioengine_fmodstudio.h +++ b/indra/llaudio/llaudioengine_fmodstudio.h @@ -51,7 +51,7 @@ public: virtual ~LLAudioEngine_FMODSTUDIO(); // initialization/startup/shutdown - virtual bool init(const S32 num_channels, void *user_data); + virtual bool init(const S32 num_channels, void *user_data, const std::string &app_title); virtual std::string getDriverName(bool verbose); virtual void allocateListener(); diff --git a/indra/llaudio/llaudioengine_openal.cpp b/indra/llaudio/llaudioengine_openal.cpp index e6ac586618..a38d8291fa 100644 --- a/indra/llaudio/llaudioengine_openal.cpp +++ b/indra/llaudio/llaudioengine_openal.cpp @@ -52,7 +52,7 @@ LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL() } // virtual -bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata) +bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata, const std::string &app_title) { mWindGen = NULL; LLAudioEngine::init(num_channels, userdata); @@ -239,6 +239,13 @@ bool LLAudioChannelOpenAL::isPlaying() bool LLAudioChannelOpenAL::updateBuffer() { + if (!mCurrentSourcep) + { + // This channel isn't associated with any source, nothing + // to be updated + return false; + } + if (LLAudioChannel::updateBuffer()) { // Base class update returned true, which means that we need to actually diff --git a/indra/llaudio/llaudioengine_openal.h b/indra/llaudio/llaudioengine_openal.h index 6639d9dfe6..366f9259e3 100644 --- a/indra/llaudio/llaudioengine_openal.h +++ b/indra/llaudio/llaudioengine_openal.h @@ -40,8 +40,8 @@ class LLAudioEngine_OpenAL : public LLAudioEngine LLAudioEngine_OpenAL(); virtual ~LLAudioEngine_OpenAL(); - virtual bool init(const S32 num_channels, void *user_data); - virtual std::string getDriverName(bool verbose); + virtual bool init(const S32 num_channels, void *user_data, const std::string &app_title); + virtual std::string getDriverName(bool verbose); virtual void allocateListener(); virtual void shutdown(); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index cb76ac6f74..56e8000400 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -650,7 +650,7 @@ bool idle_startup() #else void* window_handle = NULL; #endif - bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle); + bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle, LLAppViewer::instance()->getSecondLifeTitle()); if(init) { gAudiop->setMuted(TRUE); -- cgit v1.3 From 032c4a1b4999b117f53465e62bf932e62015a7fe Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 14 Apr 2020 21:32:10 +0300 Subject: SL-12607 WIP, take pre-sized icons from repo instead of package --- indra/llaudio/llaudioengine_fmodstudio.cpp | 21 ++++++--- indra/newview/llprogressview.cpp | 51 ++++++++++----------- .../skins/default/textures/3p_icons/fmod_logo.png | Bin 0 -> 1732 bytes .../skins/default/textures/3p_icons/havok_logo.png | Bin 0 -> 2586 bytes .../skins/default/textures/3p_icons/vivox_logo.png | Bin 0 -> 1740 bytes indra/newview/viewer_manifest.py | 21 --------- 6 files changed, 39 insertions(+), 54 deletions(-) create mode 100644 indra/newview/skins/default/textures/3p_icons/fmod_logo.png create mode 100644 indra/newview/skins/default/textures/3p_icons/havok_logo.png create mode 100644 indra/newview/skins/default/textures/3p_icons/vivox_logo.png (limited to 'indra/llaudio/llaudioengine_fmodstudio.cpp') diff --git a/indra/llaudio/llaudioengine_fmodstudio.cpp b/indra/llaudio/llaudioengine_fmodstudio.cpp index 06a5776eb1..70b3a08473 100644 --- a/indra/llaudio/llaudioengine_fmodstudio.cpp +++ b/indra/llaudio/llaudioengine_fmodstudio.cpp @@ -70,7 +70,7 @@ static inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string) { if (result == FMOD_OK) return false; - LL_DEBUGS() << string << " Error: " << FMOD_ErrorString(result) << LL_ENDL; + LL_DEBUGS("FMOD") << string << " Error: " << FMOD_ErrorString(result) << LL_ENDL; return true; } @@ -97,8 +97,6 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons << " expected:" << FMOD_VERSION << LL_ENDL; } - // In case we need to force sampling on stereo, use setSoftwareFormat here - // In this case, all sounds, PLUS wind and stream will be software. result = mSystem->setSoftwareChannels(num_channels + 2); Check_FMOD_Error(result, "FMOD::System::setSoftwareChannels"); @@ -193,6 +191,15 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons // number of channel in this case looks to be identiacal to number of max simultaneously // playing objects and we can set practically any number result = mSystem->init(num_channels + 2, fmod_flags, 0); + if (Check_FMOD_Error(result, "Error initializing FMOD Studio with default settins, retrying with other format")) + { + result = mSystem->setSoftwareFormat(44100, FMOD_SPEAKERMODE_STEREO, 0/*- ignore*/); + if (Check_FMOD_Error(result, "Error setting sotware format. Can't init.")) + { + return false; + } + result = mSystem->init(num_channels + 2, fmod_flags, 0); + } if (Check_FMOD_Error(result, "Error initializing FMOD Studio")) { // If it fails here and (result == FMOD_ERR_OUTPUT_CREATEBUFFER), @@ -251,7 +258,7 @@ void LLAudioEngine_FMODSTUDIO::allocateListener(void) mListenerp = (LLListener *) new LLListener_FMODSTUDIO(mSystem); if (!mListenerp) { - LL_WARNS() << "Listener creation failed" << LL_ENDL; + LL_WARNS("FMOD") << "Listener creation failed" << LL_ENDL; } } @@ -260,16 +267,16 @@ void LLAudioEngine_FMODSTUDIO::shutdown() { stopInternetStream(); - LL_INFOS() << "About to LLAudioEngine::shutdown()" << LL_ENDL; + LL_INFOS("FMOD") << "About to LLAudioEngine::shutdown()" << LL_ENDL; LLAudioEngine::shutdown(); - LL_INFOS() << "LLAudioEngine_FMODSTUDIO::shutdown() closing FMOD Studio" << LL_ENDL; + LL_INFOS("FMOD") << "LLAudioEngine_FMODSTUDIO::shutdown() closing FMOD Studio" << LL_ENDL; if (mSystem) { mSystem->close(); mSystem->release(); } - LL_INFOS() << "LLAudioEngine_FMODSTUDIO::shutdown() done closing FMOD Studio" << LL_ENDL; + LL_INFOS("FMOD") << "LLAudioEngine_FMODSTUDIO::shutdown() done closing FMOD Studio" << LL_ENDL; delete mListenerp; mListenerp = NULL; diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index f745d26864..b51c791621 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -381,54 +381,50 @@ void LLProgressView::initLogos() const U8 image_codec = IMG_CODEC_PNG; const LLRectf default_clip(0.f, 1.f, 1.f, 0.f); - const S32 default_height = 24; - const S32 default_width = 91; + const S32 default_height = 32; const S32 default_pad = 7; + S32 icon_width; + // We don't know final screen rect yet, so we can't precalculate position fully LLTextBox *logos_label = getChild("logos_lbl"); S32 texture_start_x = logos_label->getFont()->getWidthF32(logos_label->getText()) + default_pad; S32 texture_start_y = -3; - // Normally iamges stay in skins folder, but 3p images come from package instead - // of repository and need special handling -#ifdef LL_WINDOWS - std::string temp_str = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "3p_icons"); -#elif LL_DARWIN - // On MAC use resource directory - std::string temp_str = gDirUtilp->add(gDirUtilp->getAppRODataDir(), "3p_icons"); -#else - std::string temp_str = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "3p_icons"); -#endif + // Normally we would just preload these textures from textures.xml, + // and display them via icon control, but they are only needed on + // startup and preloaded/UI ones stay forever + // (and this code was done already so simply reused it) + std::string temp_str = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "textures", "3p_icons"); + temp_str += gDirUtilp->getDirDelimiter(); #ifdef LL_FMODSTUDIO - const S32 fmod_y_offset = 2; - loadLogo(temp_str + "fmod.png", + icon_width = 89; + loadLogo(temp_str + "fmod_logo.png", image_codec, - LLRect(texture_start_x, texture_start_y + default_height + fmod_y_offset, texture_start_x + default_width + fmod_y_offset, texture_start_y), + LLRect(texture_start_x, texture_start_y + default_height, texture_start_x + icon_width, texture_start_y), default_clip, default_clip); - texture_start_x += default_width + default_pad; + texture_start_x += icon_width + default_pad; #endif + icon_width = 100; loadLogo(temp_str + "havok_logo.png", image_codec, - LLRect(texture_start_x, texture_start_y + default_height, texture_start_x + default_width, texture_start_y), + LLRect(texture_start_x, texture_start_y + default_height, texture_start_x + icon_width, texture_start_y), default_clip, default_clip); - texture_start_x += default_width + default_pad - 2; // offset to compensate for enormous borders for vivox + texture_start_x += icon_width + default_pad; - const LLRectf vivox_clip(0.0f /*repeats*/, 0.52f /*cut starting from center*/, 0.52f, 0.0f); // non-standard icon, clip it - const LLRectf vivox_offset(0.0f, 0.23f, 0.23f, 0.0f); // keeping clipping identical to not mess up scale - const S32 vivox_y_offset = -5; + icon_width = 87; loadLogo(temp_str + "vivox_logo.png", image_codec, - LLRect(texture_start_x, texture_start_y + default_height + vivox_y_offset, texture_start_x + default_width, texture_start_y + vivox_y_offset), - vivox_clip, - vivox_offset); + LLRect(texture_start_x, texture_start_y + default_height, texture_start_x + icon_width, texture_start_y), + default_clip, + default_clip); } void LLProgressView::initStartTexture(S32 location_id, bool is_in_production) @@ -511,8 +507,11 @@ void LLProgressView::initTextures(S32 location_id, bool is_in_production) initStartTexture(location_id, is_in_production); initLogos(); - LLTextBox *logos_label = getChild("logos_lbl"); - logos_label->setVisible(true); + if (!mLogosList.empty()) + { + LLTextBox *logos_label = getChild("logos_lbl"); + logos_label->setVisible(true); + } } void LLProgressView::releaseTextures() diff --git a/indra/newview/skins/default/textures/3p_icons/fmod_logo.png b/indra/newview/skins/default/textures/3p_icons/fmod_logo.png new file mode 100644 index 0000000000..5da146bfa9 Binary files /dev/null and b/indra/newview/skins/default/textures/3p_icons/fmod_logo.png differ diff --git a/indra/newview/skins/default/textures/3p_icons/havok_logo.png b/indra/newview/skins/default/textures/3p_icons/havok_logo.png new file mode 100644 index 0000000000..1b51e23ca0 Binary files /dev/null and b/indra/newview/skins/default/textures/3p_icons/havok_logo.png differ diff --git a/indra/newview/skins/default/textures/3p_icons/vivox_logo.png b/indra/newview/skins/default/textures/3p_icons/vivox_logo.png new file mode 100644 index 0000000000..6bbd050eae Binary files /dev/null and b/indra/newview/skins/default/textures/3p_icons/vivox_logo.png differ diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index de71a66519..572c84c396 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -497,13 +497,6 @@ class WindowsManifest(ViewerManifest): self.path("*.png") self.path("*.gif") - # Copy 3p icons - with self.prefix(src=os.path.join(pkgdir, "icons"), dst="3p_icons"): - if self.args['fmodstudio'] == 'ON': - self.path("fmod.png") - self.path("havok_logo.png") - self.path("vivox_logo.png") - # Plugin host application self.path2basename(os.path.join(os.pardir, 'llplugin', 'slplugin', self.args['configuration']), @@ -973,13 +966,6 @@ class DarwinManifest(ViewerManifest): with self.prefix(src=pkgdir,dst=""): self.path("ca-bundle.crt") - # Copy 3p icons - with self.prefix(src=os.path.join(pkgdir, "icons"), dst="3p_icons"): - if self.args['fmodstudio'] == 'ON': - self.path("fmod.png") - self.path("havok_logo.png") - self.path("vivox_logo.png") - # Translations self.path("English.lproj/language.txt") self.replace_in(src="English.lproj/InfoPlist.strings", @@ -1480,13 +1466,6 @@ class Linux_i686_Manifest(LinuxManifest): relpkgdir = os.path.join(pkgdir, "lib", "release") debpkgdir = os.path.join(pkgdir, "lib", "debug") - # Copy 3p icons - with self.prefix(src=os.path.join(pkgdir, "icons"), dst="3p_icons"): - if self.args['fmodstudio'] == 'ON': - self.path("fmod.png") - self.path("havok_logo.png") - self.path("vivox_logo.png") - with self.prefix(src=relpkgdir, dst="lib"): self.path("libapr-1.so") self.path("libapr-1.so.0") -- cgit v1.3