mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-03 14:19:41 +00:00
Port SoundManager
This commit is contained in:
parent
246b06ca27
commit
8c7c89a4aa
7 changed files with 68 additions and 44 deletions
|
@ -377,7 +377,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings)
|
||||||
mEnvironment.setWindowManager (window);
|
mEnvironment.setWindowManager (window);
|
||||||
|
|
||||||
// Create sound system
|
// Create sound system
|
||||||
mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound));
|
mEnvironment.setSoundManager (new MWSound::SoundManager(mVFS.get(), mUseSound));
|
||||||
|
|
||||||
if (!mSkipMenu)
|
if (!mSkipMenu)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#ifndef HAVE_LIBSWRESAMPLE
|
#ifndef HAVE_LIBSWRESAMPLE
|
||||||
|
@ -15,6 +16,8 @@ AVAudioResampleContext * swr_alloc_set_opts( AVAudioResampleContext *avr, int64_
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <components/vfs/manager.hpp>
|
||||||
|
|
||||||
namespace MWSound
|
namespace MWSound
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -27,8 +30,10 @@ int FFmpeg_Decoder::readPacket(void *user_data, uint8_t *buf, int buf_size)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Ogre::DataStreamPtr stream = static_cast<FFmpeg_Decoder*>(user_data)->mDataStream;
|
std::istream& stream = *static_cast<FFmpeg_Decoder*>(user_data)->mDataStream;
|
||||||
return stream->read(buf, buf_size);
|
stream.read((char*)buf, buf_size);
|
||||||
|
stream.clear();
|
||||||
|
return stream.gcount();
|
||||||
}
|
}
|
||||||
catch (std::exception& )
|
catch (std::exception& )
|
||||||
{
|
{
|
||||||
|
@ -36,36 +41,36 @@ int FFmpeg_Decoder::readPacket(void *user_data, uint8_t *buf, int buf_size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int FFmpeg_Decoder::writePacket(void *user_data, uint8_t *buf, int buf_size)
|
int FFmpeg_Decoder::writePacket(void *, uint8_t *, int)
|
||||||
{
|
{
|
||||||
try
|
throw std::runtime_error("can't write to read-only stream");
|
||||||
{
|
|
||||||
Ogre::DataStreamPtr stream = static_cast<FFmpeg_Decoder*>(user_data)->mDataStream;
|
|
||||||
return stream->write(buf, buf_size);
|
|
||||||
}
|
|
||||||
catch (std::exception& )
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t FFmpeg_Decoder::seek(void *user_data, int64_t offset, int whence)
|
int64_t FFmpeg_Decoder::seek(void *user_data, int64_t offset, int whence)
|
||||||
{
|
{
|
||||||
Ogre::DataStreamPtr stream = static_cast<FFmpeg_Decoder*>(user_data)->mDataStream;
|
std::istream& stream = *static_cast<FFmpeg_Decoder*>(user_data)->mDataStream;
|
||||||
|
|
||||||
whence &= ~AVSEEK_FORCE;
|
whence &= ~AVSEEK_FORCE;
|
||||||
|
|
||||||
if(whence == AVSEEK_SIZE)
|
if(whence == AVSEEK_SIZE)
|
||||||
return stream->size();
|
{
|
||||||
|
size_t prev = stream.tellg();
|
||||||
|
stream.seekg(0, std::ios_base::end);
|
||||||
|
size_t size = stream.tellg();
|
||||||
|
stream.seekg(prev, std::ios_base::beg);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
if(whence == SEEK_SET)
|
if(whence == SEEK_SET)
|
||||||
stream->seek(static_cast<size_t>(offset));
|
stream.seekg(offset, std::ios_base::beg);
|
||||||
else if(whence == SEEK_CUR)
|
else if(whence == SEEK_CUR)
|
||||||
stream->seek(static_cast<size_t>(stream->tell()+offset));
|
stream.seekg(offset, std::ios_base::cur);
|
||||||
else if(whence == SEEK_END)
|
else if(whence == SEEK_END)
|
||||||
stream->seek(static_cast<size_t>(stream->size()+offset));
|
stream.seekg(offset, std::ios_base::end);
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return stream->tell();
|
return stream.tellg();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -186,7 +191,7 @@ size_t FFmpeg_Decoder::readAVAudioData(void *data, size_t length)
|
||||||
void FFmpeg_Decoder::open(const std::string &fname)
|
void FFmpeg_Decoder::open(const std::string &fname)
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
mDataStream = mResourceMgr.openResource(fname);
|
mDataStream = mResourceMgr->get(fname);
|
||||||
|
|
||||||
if((mFormatCtx=avformat_alloc_context()) == NULL)
|
if((mFormatCtx=avformat_alloc_context()) == NULL)
|
||||||
fail("Failed to allocate context");
|
fail("Failed to allocate context");
|
||||||
|
@ -289,7 +294,7 @@ void FFmpeg_Decoder::close()
|
||||||
avformat_close_input(&mFormatCtx);
|
avformat_close_input(&mFormatCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
mDataStream.setNull();
|
mDataStream.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FFmpeg_Decoder::getName()
|
std::string FFmpeg_Decoder::getName()
|
||||||
|
@ -409,8 +414,9 @@ size_t FFmpeg_Decoder::getSampleOffset()
|
||||||
return (int)(mNextPts*(*mStream)->codec->sample_rate) - delay;
|
return (int)(mNextPts*(*mStream)->codec->sample_rate) - delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
FFmpeg_Decoder::FFmpeg_Decoder()
|
FFmpeg_Decoder::FFmpeg_Decoder(const VFS::Manager* vfs)
|
||||||
: mFormatCtx(NULL)
|
: Sound_Decoder(vfs)
|
||||||
|
, mFormatCtx(NULL)
|
||||||
, mStream(NULL)
|
, mStream(NULL)
|
||||||
, mFrame(NULL)
|
, mFrame(NULL)
|
||||||
, mFrameSize(0)
|
, mFrameSize(0)
|
||||||
|
|
|
@ -37,7 +37,10 @@ extern "C"
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <components/files/constrainedfilestream.hpp>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <istream>
|
||||||
|
|
||||||
#include "sound_decoder.hpp"
|
#include "sound_decoder.hpp"
|
||||||
|
|
||||||
|
@ -66,7 +69,8 @@ namespace MWSound
|
||||||
|
|
||||||
bool getNextPacket();
|
bool getNextPacket();
|
||||||
|
|
||||||
Ogre::DataStreamPtr mDataStream;
|
Files::IStreamPtr mDataStream;
|
||||||
|
|
||||||
static int readPacket(void *user_data, uint8_t *buf, int buf_size);
|
static int readPacket(void *user_data, uint8_t *buf, int buf_size);
|
||||||
static int writePacket(void *user_data, uint8_t *buf, int buf_size);
|
static int writePacket(void *user_data, uint8_t *buf, int buf_size);
|
||||||
static int64_t seek(void *user_data, int64_t offset, int whence);
|
static int64_t seek(void *user_data, int64_t offset, int whence);
|
||||||
|
@ -90,7 +94,7 @@ namespace MWSound
|
||||||
FFmpeg_Decoder& operator=(const FFmpeg_Decoder &rhs);
|
FFmpeg_Decoder& operator=(const FFmpeg_Decoder &rhs);
|
||||||
FFmpeg_Decoder(const FFmpeg_Decoder &rhs);
|
FFmpeg_Decoder(const FFmpeg_Decoder &rhs);
|
||||||
|
|
||||||
FFmpeg_Decoder();
|
FFmpeg_Decoder(const VFS::Manager* vfs);
|
||||||
public:
|
public:
|
||||||
virtual ~FFmpeg_Decoder();
|
virtual ~FFmpeg_Decoder();
|
||||||
|
|
||||||
|
|
|
@ -786,7 +786,7 @@ const CachedSound& OpenAL_Output::getBuffer(const std::string &fname)
|
||||||
{
|
{
|
||||||
decoder->open(fname);
|
decoder->open(fname);
|
||||||
}
|
}
|
||||||
catch(Ogre::FileNotFoundException&)
|
catch(std::exception&)
|
||||||
{
|
{
|
||||||
std::string::size_type pos = fname.rfind('.');
|
std::string::size_type pos = fname.rfind('.');
|
||||||
if(pos == std::string::npos)
|
if(pos == std::string::npos)
|
||||||
|
|
|
@ -2,8 +2,12 @@
|
||||||
#define GAME_SOUND_SOUND_DECODER_H
|
#define GAME_SOUND_SOUND_DECODER_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <OgreResourceGroupManager.h>
|
namespace VFS
|
||||||
|
{
|
||||||
|
class Manager;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWSound
|
namespace MWSound
|
||||||
{
|
{
|
||||||
|
@ -28,7 +32,7 @@ namespace MWSound
|
||||||
|
|
||||||
struct Sound_Decoder
|
struct Sound_Decoder
|
||||||
{
|
{
|
||||||
Ogre::ResourceGroupManager &mResourceMgr;
|
const VFS::Manager* mResourceMgr;
|
||||||
|
|
||||||
virtual void open(const std::string &fname) = 0;
|
virtual void open(const std::string &fname) = 0;
|
||||||
virtual void close() = 0;
|
virtual void close() = 0;
|
||||||
|
@ -41,7 +45,7 @@ namespace MWSound
|
||||||
virtual void rewind() = 0;
|
virtual void rewind() = 0;
|
||||||
virtual size_t getSampleOffset() = 0;
|
virtual size_t getSampleOffset() = 0;
|
||||||
|
|
||||||
Sound_Decoder() : mResourceMgr(Ogre::ResourceGroupManager::getSingleton())
|
Sound_Decoder(const VFS::Manager* resourceMgr) : mResourceMgr(resourceMgr)
|
||||||
{ }
|
{ }
|
||||||
virtual ~Sound_Decoder() { }
|
virtual ~Sound_Decoder() { }
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include <openengine/misc/rng.hpp>
|
#include <openengine/misc/rng.hpp>
|
||||||
|
|
||||||
|
#include <components/vfs/manager.hpp>
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwbase/statemanager.hpp"
|
#include "../mwbase/statemanager.hpp"
|
||||||
|
@ -27,8 +29,8 @@
|
||||||
|
|
||||||
namespace MWSound
|
namespace MWSound
|
||||||
{
|
{
|
||||||
SoundManager::SoundManager(bool useSound)
|
SoundManager::SoundManager(const VFS::Manager* vfs, bool useSound)
|
||||||
: mResourceMgr(Ogre::ResourceGroupManager::getSingleton())
|
: mVFS(vfs)
|
||||||
, mOutput(new DEFAULT_OUTPUT(*this))
|
, mOutput(new DEFAULT_OUTPUT(*this))
|
||||||
, mMasterVolume(1.0f)
|
, mMasterVolume(1.0f)
|
||||||
, mSFXVolume(1.0f)
|
, mSFXVolume(1.0f)
|
||||||
|
@ -96,7 +98,7 @@ namespace MWSound
|
||||||
// Return a new decoder instance, used as needed by the output implementations
|
// Return a new decoder instance, used as needed by the output implementations
|
||||||
DecoderPtr SoundManager::getDecoder()
|
DecoderPtr SoundManager::getDecoder()
|
||||||
{
|
{
|
||||||
return DecoderPtr(new DEFAULT_DECODER);
|
return DecoderPtr(new DEFAULT_DECODER (mVFS));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert a soundId to file name, and modify the volume
|
// Convert a soundId to file name, and modify the volume
|
||||||
|
@ -208,20 +210,24 @@ namespace MWSound
|
||||||
|
|
||||||
void SoundManager::startRandomTitle()
|
void SoundManager::startRandomTitle()
|
||||||
{
|
{
|
||||||
Ogre::StringVector filelist;
|
std::vector<std::string> filelist;
|
||||||
if (mMusicFiles.find(mCurrentPlaylist) == mMusicFiles.end())
|
if (mMusicFiles.find(mCurrentPlaylist) == mMusicFiles.end())
|
||||||
{
|
{
|
||||||
#if 0
|
const std::map<std::string, VFS::File*>& index = mVFS->getIndex();
|
||||||
Ogre::StringVector groups = Ogre::ResourceGroupManager::getSingleton().getResourceGroups ();
|
|
||||||
for (Ogre::StringVector::iterator it = groups.begin(); it != groups.end(); ++it)
|
std::string pattern = "Music/" + mCurrentPlaylist;
|
||||||
|
mVFS->normalizeFilename(pattern);
|
||||||
|
|
||||||
|
std::map<std::string, VFS::File*>::const_iterator found = index.lower_bound(pattern);
|
||||||
|
while (found != index.end())
|
||||||
{
|
{
|
||||||
Ogre::StringVectorPtr resourcesInThisGroup = mResourceMgr.findResourceNames(*it,
|
if (found->first.size() >= pattern.size() && found->first.substr(0, pattern.size()) == pattern)
|
||||||
"Music/"+mCurrentPlaylist+"/*");
|
filelist.push_back(found->first);
|
||||||
filelist.insert(filelist.end(), resourcesInThisGroup->begin(), resourcesInThisGroup->end());
|
++found;
|
||||||
}
|
}
|
||||||
|
|
||||||
mMusicFiles[mCurrentPlaylist] = filelist;
|
mMusicFiles[mCurrentPlaylist] = filelist;
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
filelist = mMusicFiles[mCurrentPlaylist];
|
filelist = mMusicFiles[mCurrentPlaylist];
|
||||||
|
|
|
@ -8,12 +8,16 @@
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
#include <OgreVector3.h>
|
#include <OgreVector3.h>
|
||||||
#include <OgreResourceGroupManager.h>
|
|
||||||
|
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
#include "../mwbase/soundmanager.hpp"
|
#include "../mwbase/soundmanager.hpp"
|
||||||
|
|
||||||
|
namespace VFS
|
||||||
|
{
|
||||||
|
class Manager;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWSound
|
namespace MWSound
|
||||||
{
|
{
|
||||||
class Sound_Output;
|
class Sound_Output;
|
||||||
|
@ -27,12 +31,12 @@ namespace MWSound
|
||||||
|
|
||||||
class SoundManager : public MWBase::SoundManager
|
class SoundManager : public MWBase::SoundManager
|
||||||
{
|
{
|
||||||
Ogre::ResourceGroupManager& mResourceMgr;
|
const VFS::Manager* mVFS;
|
||||||
|
|
||||||
std::auto_ptr<Sound_Output> mOutput;
|
std::auto_ptr<Sound_Output> mOutput;
|
||||||
|
|
||||||
// Caches available music tracks by <playlist name, (sound files) >
|
// Caches available music tracks by <playlist name, (sound files) >
|
||||||
std::map<std::string, Ogre::StringVector> mMusicFiles;
|
std::map<std::string, std::vector<std::string> > mMusicFiles;
|
||||||
std::string mLastPlayedMusic; // The music file that was last played
|
std::string mLastPlayedMusic; // The music file that was last played
|
||||||
|
|
||||||
float mMasterVolume;
|
float mMasterVolume;
|
||||||
|
@ -74,7 +78,7 @@ namespace MWSound
|
||||||
friend class OpenAL_Output;
|
friend class OpenAL_Output;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SoundManager(bool useSound);
|
SoundManager(const VFS::Manager* vfs, bool useSound);
|
||||||
virtual ~SoundManager();
|
virtual ~SoundManager();
|
||||||
|
|
||||||
virtual void processChangedSettings(const Settings::CategorySettingVector& settings);
|
virtual void processChangedSettings(const Settings::CategorySettingVector& settings);
|
||||||
|
|
Loading…
Reference in a new issue