|
|
|
@ -14,6 +14,7 @@
|
|
|
|
|
#include <components/vfs/pathutil.hpp>
|
|
|
|
|
|
|
|
|
|
#include "../mwbase/environment.hpp"
|
|
|
|
|
#include "../mwbase/mechanicsmanager.hpp"
|
|
|
|
|
#include "../mwbase/statemanager.hpp"
|
|
|
|
|
#include "../mwbase/world.hpp"
|
|
|
|
|
|
|
|
|
@ -131,15 +132,6 @@ namespace MWSound
|
|
|
|
|
|
|
|
|
|
Log(Debug::Info) << stream.str();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: dehardcode this
|
|
|
|
|
std::vector<std::string> titleMusic;
|
|
|
|
|
std::string_view titlefile = "music/special/morrowind title.mp3";
|
|
|
|
|
if (mVFS->exists(titlefile))
|
|
|
|
|
titleMusic.emplace_back(titlefile);
|
|
|
|
|
else
|
|
|
|
|
Log(Debug::Warning) << "Title music not found";
|
|
|
|
|
mMusicFiles["Title"] = titleMusic;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SoundManager::~SoundManager()
|
|
|
|
@ -250,7 +242,7 @@ namespace MWSound
|
|
|
|
|
if (filename.empty())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Log(Debug::Info) << "Playing " << filename;
|
|
|
|
|
Log(Debug::Info) << "Playing \"" << filename << "\"";
|
|
|
|
|
mLastPlayedMusic = filename;
|
|
|
|
|
|
|
|
|
|
DecoderPtr decoder = getDecoder();
|
|
|
|
@ -260,7 +252,7 @@ namespace MWSound
|
|
|
|
|
}
|
|
|
|
|
catch (std::exception& e)
|
|
|
|
|
{
|
|
|
|
|
Log(Debug::Error) << "Failed to load audio from " << filename << ": " << e.what();
|
|
|
|
|
Log(Debug::Error) << "Failed to load audio from \"" << filename << "\": " << e.what();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -274,7 +266,7 @@ namespace MWSound
|
|
|
|
|
mOutput->streamSound(decoder, mMusic.get());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SoundManager::advanceMusic(const std::string& filename)
|
|
|
|
|
void SoundManager::advanceMusic(const std::string& filename, float fadeOut)
|
|
|
|
|
{
|
|
|
|
|
if (!isMusicPlaying())
|
|
|
|
|
{
|
|
|
|
@ -284,7 +276,7 @@ namespace MWSound
|
|
|
|
|
|
|
|
|
|
mNextMusic = filename;
|
|
|
|
|
|
|
|
|
|
mMusic->setFadeout(1.f);
|
|
|
|
|
mMusic->setFadeout(fadeOut);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SoundManager::startRandomTitle()
|
|
|
|
@ -319,14 +311,28 @@ namespace MWSound
|
|
|
|
|
tracklist.pop_back();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SoundManager::streamMusic(const std::string& filename)
|
|
|
|
|
bool SoundManager::isMusicPlaying()
|
|
|
|
|
{
|
|
|
|
|
advanceMusic("Music/" + filename);
|
|
|
|
|
return mMusic && mOutput->isStreamPlaying(mMusic.get());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SoundManager::isMusicPlaying()
|
|
|
|
|
void SoundManager::streamMusic(const std::string& filename, MusicType type, float fade)
|
|
|
|
|
{
|
|
|
|
|
return mMusic && mOutput->isStreamPlaying(mMusic.get());
|
|
|
|
|
const auto mechanicsManager = MWBase::Environment::get().getMechanicsManager();
|
|
|
|
|
|
|
|
|
|
// Can not interrupt scripted music by built-in playlists
|
|
|
|
|
if (mechanicsManager->getMusicType() == MusicType::Scripted && type != MusicType::Scripted
|
|
|
|
|
&& type != MusicType::Special)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
std::string normalizedName = VFS::Path::normalizeFilename(filename);
|
|
|
|
|
|
|
|
|
|
mechanicsManager->setMusicType(type);
|
|
|
|
|
advanceMusic(normalizedName, fade);
|
|
|
|
|
if (type == MWSound::MusicType::Battle)
|
|
|
|
|
mCurrentPlaylist = "Battle";
|
|
|
|
|
else if (type == MWSound::MusicType::Explore)
|
|
|
|
|
mCurrentPlaylist = "Explore";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SoundManager::playPlaylist(const std::string& playlist)
|
|
|
|
@ -337,7 +343,8 @@ namespace MWSound
|
|
|
|
|
if (mMusicFiles.find(playlist) == mMusicFiles.end())
|
|
|
|
|
{
|
|
|
|
|
std::vector<std::string> filelist;
|
|
|
|
|
for (const auto& name : mVFS->getRecursiveDirectoryIterator("Music/" + playlist + '/'))
|
|
|
|
|
auto playlistPath = Misc::ResourceHelpers::correctMusicPath(playlist) + '/';
|
|
|
|
|
for (const auto& name : mVFS->getRecursiveDirectoryIterator(playlistPath))
|
|
|
|
|
filelist.push_back(name);
|
|
|
|
|
|
|
|
|
|
mMusicFiles[playlist] = filelist;
|
|
|
|
@ -1127,6 +1134,14 @@ namespace MWSound
|
|
|
|
|
if (!mOutput->isInitialized() || mPlaybackPaused)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
MWBase::StateManager::State state = MWBase::Environment::get().getStateManager()->getState();
|
|
|
|
|
if (state == MWBase::StateManager::State_NoGame && !isMusicPlaying())
|
|
|
|
|
{
|
|
|
|
|
std::string titlefile = "music/special/morrowind title.mp3";
|
|
|
|
|
if (mVFS->exists(titlefile))
|
|
|
|
|
streamMusic(titlefile, MWSound::MusicType::Special);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
updateSounds(duration);
|
|
|
|
|
if (MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_NoGame)
|
|
|
|
|
{
|
|
|
|
|