diff --git a/CMakeLists.txt b/CMakeLists.txt index cd058c570..34925152a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -90,7 +90,15 @@ set(OENGINE_GUI ${LIBDIR}/openengine/gui/events.cpp ${LIBDIR}/openengine/gui/manager.cpp ) -set(OENGINE_ALL ${OENGINE_OGRE} ${OENGINE_GUI}) +set(OENGINE_SOUND + # Mangle and OEngine sound files are sort of intertwined, so put + # them together here + ${LIBDIR}/openengine/sound/sndmanager.cpp + ${LIBDIR}/mangle/sound/sources/audiere_source.cpp + ${LIBDIR}/mangle/sound/outputs/openal_out.cpp + ${LIBDIR}/mangle/stream/clients/audiere_file.cpp +) +set(OENGINE_ALL ${OENGINE_OGRE} ${OENGINE_GUI} ${OENGINE_SOUND}) source_group(libs\\openengine FILES ${OENGINE_ALL}) set(OPENMW_LIBS ${MANGLE_ALL} ${OENGINE_ALL}) @@ -110,6 +118,8 @@ find_package(OGRE REQUIRED) find_package(Boost REQUIRED COMPONENTS system filesystem program_options thread) find_package(OIS REQUIRED) find_package(Iconv REQUIRED) +find_package(OpenAL REQUIRED) +find_package(Audiere REQUIRED) include_directories("." ${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre ${OIS_INCLUDE_DIR} ${Boost_INCLUDE_DIR} diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index a43119c61..c978bc2db 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -183,6 +183,8 @@ target_link_libraries(openmw ${OGRE_LIBRARIES} ${OIS_LIBRARIES} ${Boost_LIBRARIES} + ${OPENAL_LIBRARY} + ${AUDIERE_LIBRARY} ${ICONV_LIBRARIES} caelum MyGUIEngine diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index b67bcd0ac..ad12f910b 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -233,7 +233,8 @@ void OMW::Engine::go() mExtensions, mNewGame); // Create sound system - mEnvironment.mSoundManager = new MWSound::SoundManager; + mEnvironment.mSoundManager = new MWSound::SoundManager(mOgre.getRoot(), + mOgre.getCamera()); // Create script system mScriptContext = new MWScript::CompilerContext (MWScript::CompilerContext::Type_Full, diff --git a/apps/openmw/mwsound/soundmanager.cpp b/apps/openmw/mwsound/soundmanager.cpp index bfe51686b..87f6b9bdd 100644 --- a/apps/openmw/mwsound/soundmanager.cpp +++ b/apps/openmw/mwsound/soundmanager.cpp @@ -1,12 +1,67 @@ #include "soundmanager.hpp" -#include // TODO remove this line, once the real code is in place. - #include +#include + +/* Set up the sound manager to use Audiere for input (reading sound + files) and OpenAL for output. + */ +#include +#define SOUND_FACTORY OpenAL_Audiere_Factory +/* + We could allow several options for libraries via external #defines + if we like, controlled through CMake. The only things that need to + change is the include and #define above, and of course the linker + parameters. + */ + +using namespace Mangle::Sound; + +/* Set the position on a sound based on a Ptr. TODO: We do not support + tracking moving objects yet, once a sound is started it stays in + the same place until it finishes. + + This obviously has to be fixed at some point for player/npc + footstep sounds and the like. However, updating all sounds each + frame is expensive, so there should be a special flag for sounds + that need to track their attached object. + */ +static void setPos(SoundPtr snd, MWWorld::Ptr ref) +{ + // Get sound position from the reference + float *pos = ref.getCellRef().pos.pos; + + // Move the sound. Might need to convert coordinates, test. + snd->setPos(pos[0], pos[1], pos[2]); +} + namespace MWSound { + struct SoundManager::SoundImpl + { + OEngine::Sound::SoundManager mgr; + + SoundImpl() + : mgr(SoundFactoryPtr(new SOUND_FACTORY)) + {} + + std::map mSounds; // object, sound + }; + + SoundManager::SoundManager(Ogre::Root *root, Ogre::Camera *camera) + { + mData = new SoundImpl; + + // TODO: Set up updater and camera listener. + } + + SoundManager::~SoundManager() + { + delete mData; + } + void SoundManager::say (MWWorld::Ptr reference, const std::string& filename, const std::string& text, Interpreter::Context& context) { @@ -43,7 +98,7 @@ namespace MWSound << " at volume " << volume << ", at pitch " << pitch << std::endl; - mSounds[reference.getRefData().getHandle()] = soundId; + mData->mSounds[reference.getRefData().getHandle()] = soundId; } void SoundManager::stopSound3D (MWWorld::Ptr reference, const std::string& soundId, @@ -53,16 +108,16 @@ namespace MWSound << "sound effect : stop playing sound " << soundId << " from " << reference.getRefData().getHandle() << std::endl; - mSounds[reference.getRefData().getHandle()] = ""; + mData->mSounds[reference.getRefData().getHandle()] = ""; } bool SoundManager::getSoundPlaying (MWWorld::Ptr reference, const std::string& soundId, Interpreter::Context& context) const { std::map::const_iterator iter = - mSounds.find (reference.getRefData().getHandle()); + mData->mSounds.find (reference.getRefData().getHandle()); - if (iter==mSounds.end()) + if (iter==mData->mSounds.end()) return false; return iter->second==soundId; diff --git a/apps/openmw/mwsound/soundmanager.hpp b/apps/openmw/mwsound/soundmanager.hpp index 5a79c0c27..e42331223 100644 --- a/apps/openmw/mwsound/soundmanager.hpp +++ b/apps/openmw/mwsound/soundmanager.hpp @@ -11,26 +11,28 @@ namespace Interpreter class Context; } +namespace Ogre +{ + class Root; + class Camera; +} + namespace MWSound { - // Note to the sound implementor (can be removed once the implementation is complete): - // - // - the dummy implementation allows only one sound effect per object at a time. I am - // not sure, if that is what Morrowind does. Beyond the dummy code in this class the script - // system does not make any assumption about the number of sound effects. - // - // - all text-output (error messages and such) must be directed through the - // context.messageBox interface. - // - // - the -> script syntax is not implemented yet ( script instructions of the type - // npc_x -> say "file", "text" - // aren't working) + // Note: the -> script syntax is not implemented yet ( script + // instructions of the type npc_x -> say "file", "text" aren't + // working) class SoundManager { - std::map mSounds; // object, sound (for testing only) + // Hide implementation details - engine.cpp is compiling + // enough as it is. + struct SoundImpl; + SoundImpl *mData; public: + SoundManager(Ogre::Root*, Ogre::Camera*); + ~SoundManager(); void say (MWWorld::Ptr reference, const std::string& filename, const std::string& text, Interpreter::Context& context); diff --git a/cmake/FindAudiere.cmake b/cmake/FindAudiere.cmake new file mode 100644 index 000000000..4cc1fb2df --- /dev/null +++ b/cmake/FindAudiere.cmake @@ -0,0 +1,57 @@ +# Locate Audiere +# This module defines +# AUDIERE_LIBRARY +# AUDIERE_FOUND, if false, do not try to link to Audiere +# AUDIERE_INCLUDE_DIR, where to find the headers +# +# Created by Nicolay Korslund for OpenMW (http://openmw.com) +# +# More or less a direct ripoff of FindOpenAL.cmake by Eric Wing. + +#============================================================================= +# Copyright 2005-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distributed this file outside of CMake, substitute the full +# License text for the above reference.) + + +FIND_PATH(AUDIERE_INCLUDE_DIR audiere.h + HINTS + PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local + /usr + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt +) + +FIND_LIBRARY(AUDIERE_LIBRARY + NAMES audiere + HINTS + PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64 + PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local + /usr + /sw + /opt/local + /opt/csw + /opt +) + +SET(AUDIERE_FOUND "NO") +IF(AUDIERE_LIBRARY AND AUDIERE_INCLUDE_DIR) + SET(AUDIERE_FOUND "YES") +ENDIF(AUDIERE_LIBRARY AND AUDIERE_INCLUDE_DIR) + diff --git a/libs/mangle b/libs/mangle index c7b179d65..fb2d077ca 160000 --- a/libs/mangle +++ b/libs/mangle @@ -1 +1 @@ -Subproject commit c7b179d6546688208528c8eef681d42b7c1ec7be +Subproject commit fb2d077ca9935374dd46576e643d111feb325c90 diff --git a/libs/openengine b/libs/openengine index c04d72cbe..b9d4dc448 160000 --- a/libs/openengine +++ b/libs/openengine @@ -1 +1 @@ -Subproject commit c04d72cbe380217c2d1d60f8a2c6e4810fe4c050 +Subproject commit b9d4dc448bc3be908653f9dea3c3450fb85ed107