mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 23:23:52 +00:00
Added new FileLibrary class to handle music, this fixes a number of issues.
This commit is contained in:
parent
54353794e5
commit
054a176c86
6 changed files with 235 additions and 18 deletions
|
@ -118,8 +118,7 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
|
||||||
// sound
|
// sound
|
||||||
if (mUseSound)
|
if (mUseSound)
|
||||||
{
|
{
|
||||||
if (!mEnvironment.mSoundManager->isMusicPlaying())
|
mEnvironment.mSoundManager->playPlaylist();
|
||||||
mEnvironment.mSoundManager->startRandomTitle();
|
|
||||||
|
|
||||||
mEnvironment.mSoundManager->update (evt.timeSinceLastFrame);
|
mEnvironment.mSoundManager->update (evt.timeSinceLastFrame);
|
||||||
}
|
}
|
||||||
|
@ -389,7 +388,7 @@ void OMW::Engine::go()
|
||||||
mOgre->getRoot()->addFrameListener (this);
|
mOgre->getRoot()->addFrameListener (this);
|
||||||
|
|
||||||
// Play some good 'ol tunes
|
// Play some good 'ol tunes
|
||||||
mEnvironment.mSoundManager->startRandomTitle();
|
mEnvironment.mSoundManager->playPlaylist(std::string("Explore"));
|
||||||
|
|
||||||
// scripts
|
// scripts
|
||||||
if (mCompileAll)
|
if (mCompileAll)
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include <components/file_finder/file_finder.hpp>
|
#include <components/file_finder/file_finder.hpp>
|
||||||
#include <components/esm_store/store.hpp>
|
#include <components/esm_store/store.hpp>
|
||||||
|
|
||||||
|
|
||||||
#include "../mwworld/environment.hpp"
|
#include "../mwworld/environment.hpp"
|
||||||
#include "../mwworld/world.hpp"
|
#include "../mwworld/world.hpp"
|
||||||
#include "../mwworld/player.hpp"
|
#include "../mwworld/player.hpp"
|
||||||
|
@ -45,7 +44,6 @@
|
||||||
|
|
||||||
using namespace Mangle::Sound;
|
using namespace Mangle::Sound;
|
||||||
typedef OEngine::Sound::SoundManager OEManager;
|
typedef OEngine::Sound::SoundManager OEManager;
|
||||||
////typedef OEngine::Sound::SoundManagerPtr OEManagerPtr;
|
|
||||||
|
|
||||||
// Set the position on a sound based on a Ptr.
|
// Set the position on a sound based on a Ptr.
|
||||||
static void setPos(SoundPtr &snd, const MWWorld::Ptr ref)
|
static void setPos(SoundPtr &snd, const MWWorld::Ptr ref)
|
||||||
|
@ -69,11 +67,21 @@ namespace MWSound
|
||||||
, mgr(new OEManager(SoundFactoryPtr(new SOUND_FACTORY)))
|
, mgr(new OEManager(SoundFactoryPtr(new SOUND_FACTORY)))
|
||||||
, updater(mgr)
|
, updater(mgr)
|
||||||
, cameraTracker(mgr)
|
, cameraTracker(mgr)
|
||||||
|
, mCurrentPlaylist(NULL)
|
||||||
{
|
{
|
||||||
if(useSound)
|
if(useSound)
|
||||||
{
|
{
|
||||||
// Make a list of all the sounds
|
// Temporary list of all sound directories
|
||||||
Files::PathContainer soundDirs;
|
Files::PathContainer soundDirs;
|
||||||
|
|
||||||
|
// The music library will accept these filetypes
|
||||||
|
// If none is given then it will accept all filetypes
|
||||||
|
std::vector<std::string> acceptableExtensions;
|
||||||
|
acceptableExtensions.push_back(".mp3");
|
||||||
|
acceptableExtensions.push_back(".wav");
|
||||||
|
acceptableExtensions.push_back(".ogg");
|
||||||
|
acceptableExtensions.push_back(".flac");
|
||||||
|
|
||||||
for (Files::PathContainer::const_iterator it = dataDirs.begin(); it != dataDirs.end(); ++it)
|
for (Files::PathContainer::const_iterator it = dataDirs.begin(); it != dataDirs.end(); ++it)
|
||||||
{
|
{
|
||||||
soundDirs.push_back( *it / std::string("Sound"));
|
soundDirs.push_back( *it / std::string("Sound"));
|
||||||
|
@ -83,17 +91,14 @@ namespace MWSound
|
||||||
Files::FileLister(*it, mSoundFiles, true);
|
Files::FileLister(*it, mSoundFiles, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a list of all the music tracks
|
|
||||||
Files::PathContainer musicDirs;
|
|
||||||
for (Files::PathContainer::const_iterator it = dataDirs.begin(); it != dataDirs.end(); ++it)
|
for (Files::PathContainer::const_iterator it = dataDirs.begin(); it != dataDirs.end(); ++it)
|
||||||
{
|
{
|
||||||
musicDirs.push_back( *it / std::string("Music") / std::string("Explore"));
|
mMusicLibrary.add(*it / std::string("Music"), true, mFSStrict, acceptableExtensions);
|
||||||
}
|
|
||||||
for (Files::PathContainer::const_iterator it = musicDirs.begin(); it != musicDirs.end(); ++it)
|
|
||||||
{
|
|
||||||
Files::FileLister(*it, mMusicFiles, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string anything = "anything"; // anything is better that a segfault
|
||||||
|
mCurrentPlaylist = mMusicLibrary.section(anything, mFSStrict); // now points to an empty path
|
||||||
|
|
||||||
std::cout << "Sound output: " << SOUND_OUT << std::endl;
|
std::cout << "Sound output: " << SOUND_OUT << std::endl;
|
||||||
std::cout << "Sound decoder: " << SOUND_IN << std::endl;
|
std::cout << "Sound decoder: " << SOUND_IN << std::endl;
|
||||||
// Attach the camera to the camera tracker
|
// Attach the camera to the camera tracker
|
||||||
|
@ -287,7 +292,8 @@ namespace MWSound
|
||||||
|
|
||||||
void SoundManager::streamMusic(const std::string& filename)
|
void SoundManager::streamMusic(const std::string& filename)
|
||||||
{
|
{
|
||||||
std::string filePath = Files::FileListLocator(mMusicFiles, filename, mFSStrict);
|
std::cout << filename << std::endl;
|
||||||
|
std::string filePath = mMusicLibrary.locate(filename, mFSStrict).string();
|
||||||
if(!filePath.empty())
|
if(!filePath.empty())
|
||||||
{
|
{
|
||||||
streamMusicFull(filePath);
|
streamMusicFull(filePath);
|
||||||
|
@ -296,11 +302,11 @@ namespace MWSound
|
||||||
|
|
||||||
void SoundManager::startRandomTitle()
|
void SoundManager::startRandomTitle()
|
||||||
{
|
{
|
||||||
if(!mMusicFiles.empty())
|
if(mCurrentPlaylist && !mCurrentPlaylist->empty())
|
||||||
{
|
{
|
||||||
Files::PathContainer::iterator fileIter = mMusicFiles.begin();
|
Files::PathContainer::const_iterator fileIter = mCurrentPlaylist->begin();
|
||||||
srand( time(NULL) );
|
srand( time(NULL) );
|
||||||
int r = rand() % mMusicFiles.size() + 1; //old random code
|
int r = rand() % mCurrentPlaylist->size() + 1; //old random code
|
||||||
|
|
||||||
std::advance(fileIter, r - 1);
|
std::advance(fileIter, r - 1);
|
||||||
std::string music = fileIter->string();
|
std::string music = fileIter->string();
|
||||||
|
@ -327,6 +333,42 @@ namespace MWSound
|
||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SoundManager::setPlaylist(std::string playlist)
|
||||||
|
{
|
||||||
|
const Files::PathContainer* previousPlaylist;
|
||||||
|
previousPlaylist = mCurrentPlaylist;
|
||||||
|
if(mMusicLibrary.containsSection(playlist, mFSStrict))
|
||||||
|
{
|
||||||
|
mCurrentPlaylist = mMusicLibrary.section(playlist, mFSStrict);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Warning: playlist named " << playlist << " does not exist.\n";
|
||||||
|
}
|
||||||
|
return previousPlaylist == mCurrentPlaylist;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundManager::playPlaylist(std::string playlist)
|
||||||
|
{
|
||||||
|
if (playlist == "")
|
||||||
|
{
|
||||||
|
if(!isMusicPlaying())
|
||||||
|
{
|
||||||
|
startRandomTitle();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!setPlaylist(playlist))
|
||||||
|
{
|
||||||
|
startRandomTitle();
|
||||||
|
}
|
||||||
|
else if (!isMusicPlaying())
|
||||||
|
{
|
||||||
|
startRandomTitle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SoundManager::say (MWWorld::Ptr ptr, const std::string& filename)
|
void SoundManager::say (MWWorld::Ptr ptr, const std::string& filename)
|
||||||
{
|
{
|
||||||
// The range values are not tested
|
// The range values are not tested
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <openengine/sound/sndmanager.hpp>
|
#include <openengine/sound/sndmanager.hpp>
|
||||||
#include <components/files/fileops.hpp>
|
#include <components/files/fileops.hpp>
|
||||||
#include <components/file_finder/file_finder.hpp>
|
#include <components/file_finder/file_finder.hpp>
|
||||||
|
#include <components/files/filelibrary.hpp>
|
||||||
|
|
||||||
#include "../mwworld/ptr.hpp"
|
#include "../mwworld/ptr.hpp"
|
||||||
|
|
||||||
|
@ -86,7 +87,9 @@ namespace MWSound
|
||||||
|
|
||||||
Files::PathContainer mSoundFiles;
|
Files::PathContainer mSoundFiles;
|
||||||
|
|
||||||
Files::PathContainer mMusicFiles;
|
Files::FileLibrary mMusicLibrary;
|
||||||
|
|
||||||
|
const Files::PathContainer* mCurrentPlaylist;
|
||||||
|
|
||||||
std::string lookup(const std::string &soundId,
|
std::string lookup(const std::string &soundId,
|
||||||
float &volume, float &min, float &max);
|
float &volume, float &min, float &max);
|
||||||
|
@ -115,6 +118,17 @@ namespace MWSound
|
||||||
|
|
||||||
bool isMusicPlaying();
|
bool isMusicPlaying();
|
||||||
|
|
||||||
|
bool setPlaylist(std::string playlist="");
|
||||||
|
///< Set the playlist to an existing folder
|
||||||
|
/// \param name of the folder that contains the playlist
|
||||||
|
/// if none is set then it is set to an empty playlist
|
||||||
|
/// \return Return true if the previous playlist was the same
|
||||||
|
|
||||||
|
void playPlaylist(std::string playlist="");
|
||||||
|
///< Start playing music from the selected folder
|
||||||
|
/// \param name of the folder that contains the playlist
|
||||||
|
/// if none is set then it plays from the current playlist
|
||||||
|
|
||||||
void say (MWWorld::Ptr reference, const std::string& filename);
|
void say (MWWorld::Ptr reference, const std::string& filename);
|
||||||
///< Make an actor say some text.
|
///< Make an actor say some text.
|
||||||
/// \param filename name of a sound file in "Sound/Vo/" in the data directory.
|
/// \param filename name of a sound file in "Sound/Vo/" in the data directory.
|
||||||
|
|
|
@ -44,6 +44,7 @@ add_component_dir (misc
|
||||||
|
|
||||||
add_component_dir (files
|
add_component_dir (files
|
||||||
linuxpath windowspath macospath fixedpath multidircollection collections fileops configurationmanager
|
linuxpath windowspath macospath fixedpath multidircollection collections fileops configurationmanager
|
||||||
|
filelibrary
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (compiler
|
add_component_dir (compiler
|
||||||
|
|
113
components/files/filelibrary.cpp
Normal file
113
components/files/filelibrary.cpp
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
#include "filelibrary.hpp"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
|
namespace Files
|
||||||
|
{
|
||||||
|
// Looks for a string in a vector of strings
|
||||||
|
bool containsVectorString(const StringVector& list, const std::string& str)
|
||||||
|
{
|
||||||
|
for (StringVector::const_iterator iter = list.begin();
|
||||||
|
iter != list.end(); iter++)
|
||||||
|
{
|
||||||
|
if (*iter == str)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Searches a path and adds the results to the library
|
||||||
|
void FileLibrary::add(const boost::filesystem::path &root, bool recursive, bool strict,
|
||||||
|
const StringVector &acceptableExtensions)
|
||||||
|
{
|
||||||
|
PathContainer list;
|
||||||
|
std::string fileExtension;
|
||||||
|
std::string type;
|
||||||
|
FileLister(root, list, recursive);
|
||||||
|
|
||||||
|
for (PathContainer::iterator listIter = list.begin();
|
||||||
|
listIter != list.end(); ++listIter)
|
||||||
|
{
|
||||||
|
if( !acceptableExtensions.empty() )
|
||||||
|
{
|
||||||
|
fileExtension = listIter->extension().string();
|
||||||
|
boost::algorithm::to_lower(fileExtension);
|
||||||
|
if(!containsVectorString(acceptableExtensions, fileExtension))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
type = listIter->parent_path().leaf().string();
|
||||||
|
if (!strict)
|
||||||
|
boost::algorithm::to_lower(type);
|
||||||
|
|
||||||
|
mMap[type].push_back(*listIter);
|
||||||
|
//std::cout << "Added path: " << listIter->string() << " in section "<< type <<std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if the named section exists
|
||||||
|
bool FileLibrary::containsSection(std::string sectionName, bool strict)
|
||||||
|
{
|
||||||
|
if (!strict)
|
||||||
|
boost::algorithm::to_lower(sectionName);
|
||||||
|
StringPathContMap::const_iterator mapIter = mMap.find(sectionName);
|
||||||
|
if (mapIter == mMap.end())
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a pointer to const for a section of the library
|
||||||
|
const PathContainer* FileLibrary::section(std::string sectionName, bool strict)
|
||||||
|
{
|
||||||
|
if (!strict)
|
||||||
|
boost::algorithm::to_lower(sectionName);
|
||||||
|
StringPathContMap::const_iterator mapIter = mMap.find(sectionName);
|
||||||
|
if (mapIter == mMap.end())
|
||||||
|
{
|
||||||
|
//std::cout << "Empty\n";
|
||||||
|
return &mEmptyPath;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return &(mapIter->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Searches the library for an item and returns a boost path to it
|
||||||
|
boost::filesystem::path FileLibrary::locate(std::string item, bool strict, std::string sectionName)
|
||||||
|
{
|
||||||
|
boost::filesystem::path result("");
|
||||||
|
if (sectionName == "")
|
||||||
|
{
|
||||||
|
for(StringPathContMap::iterator iter = mMap.begin(); iter != mMap.end(); iter++)
|
||||||
|
{
|
||||||
|
result = FileListLocator(iter->second, boost::filesystem::path(item), strict);
|
||||||
|
if (result != boost::filesystem::path(""))
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!containsSection(sectionName, strict))
|
||||||
|
{
|
||||||
|
std::cout << "Warning: There is no section named " << sectionName << "\n";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result = FileListLocator(mMap[sectionName], boost::filesystem::path(item), strict);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints all the available sections, used for debugging
|
||||||
|
void FileLibrary::printSections()
|
||||||
|
{
|
||||||
|
for(StringPathContMap::const_iterator mapIter = mMap.begin();
|
||||||
|
mapIter != mMap.end(); mapIter++)
|
||||||
|
{
|
||||||
|
std::cout << mapIter->first <<std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
48
components/files/filelibrary.hpp
Normal file
48
components/files/filelibrary.hpp
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
#ifndef COMPONENTS_FILES_FILELIBRARY_HPP
|
||||||
|
#define COMPONENTS_FILES_FILELIBRARY_HPP
|
||||||
|
|
||||||
|
#include <components/files/fileops.hpp>
|
||||||
|
|
||||||
|
namespace Files
|
||||||
|
{
|
||||||
|
typedef std::map<std::string, PathContainer> StringPathContMap;
|
||||||
|
typedef std::vector<std::string> StringVector;
|
||||||
|
|
||||||
|
/// Looks for a string in a vector of strings
|
||||||
|
bool containsVectorString(const StringVector& list, const std::string& str);
|
||||||
|
|
||||||
|
/// \brief Searches directories and makes lists of files according to folder name
|
||||||
|
class FileLibrary
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
StringPathContMap mMap;
|
||||||
|
PathContainer mEmptyPath;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Searches a path and adds the results to the library
|
||||||
|
/// Recursive search and fs strict options are available
|
||||||
|
/// Takes a vector of acceptable files extensions, if none is given it lists everything.
|
||||||
|
void add(const boost::filesystem::path &root, bool recursive, bool strict,
|
||||||
|
const StringVector &acceptableExtensions);
|
||||||
|
|
||||||
|
/// Returns true if the named section exists
|
||||||
|
/// You can run this check before running section()
|
||||||
|
bool containsSection(std::string sectionName, bool strict);
|
||||||
|
|
||||||
|
/// Returns a pointer to const for a section of the library
|
||||||
|
/// which is essentially a PathContainer.
|
||||||
|
/// If the section does not exists it returns a pointer to an empty path.
|
||||||
|
const PathContainer* section(std::string sectionName, bool strict);
|
||||||
|
|
||||||
|
/// Searches the library for an item and returns a boost path to it
|
||||||
|
/// Optionally you can provide a specific section
|
||||||
|
/// The result is the first that comes up according to alphabetical
|
||||||
|
/// section naming
|
||||||
|
boost::filesystem::path locate(std::string item, bool strict, std::string sectionName="");
|
||||||
|
|
||||||
|
/// Prints all the available sections, used for debugging
|
||||||
|
void printSections();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue