]> Dogcows Code - chaz/yoink/blobdiff - src/Moof/Sound.cc
library class revamped as manager, goodbye tilemap
[chaz/yoink] / src / Moof / Sound.cc
index ca3ecfec8117fb93386edf6128c507d5ae41bcc2..f8f05baf75717aa376ae85eaebc950fc79d8db5e 100644 (file)
 #include <list>
 #include <string>
 
+#include <boost/algorithm/string.hpp>
+
 #include <AL/al.h>
+#include <AL/alc.h>
 #include <vorbis/codec.h>
 #include <vorbis/vorbisfile.h>
 
-#include "Core.hh"
 #include "Error.hh"
-#include "Library.hh"
+#include "Manager.hh"
 #include "Log.hh"
 #include "Sound.hh"
 #include "Timer.hh"
@@ -62,16 +64,14 @@ public:
        class Buffer;
        typedef boost::shared_ptr<Buffer> BufferP;
        
-       class Buffer : public Library<Buffer>
+       class Buffer : public Manager<Buffer>
        {
        public:
 
-               explicit Buffer(const std::string& name) :
-                       Library<Buffer>(name),
+               Buffer() :
                        mBuffer(-1)
                {
                        mOggStream.datasource = 0;
-                       openFile();
                }
 
                ~Buffer()
@@ -84,7 +84,7 @@ public:
                }
 
 
-               void openFile()
+               void init(const std::string& name)
                {
                        if (mOggStream.datasource)
                        {
@@ -92,14 +92,13 @@ public:
                                mOggStream.datasource = 0;
                        }
 
-                       std::string filePath = Sound::getPath(getName());
-                       int result = ov_fopen((char*)filePath.c_str(), &mOggStream);
+                       std::string path = Sound::getPath(name);
+                       int result = ov_fopen((char*)path.c_str(), &mOggStream);
 
                        if (result < 0)
                        {
-                               logWarning << "error while loading sound "
-                                                  << getName() << std::endl;
-                               throw Error(Error::UNKNOWN_AUDIO_FORMAT, getName());
+                               logWarning << "couldn't load sound: " << path << std::endl;
+                               throw Error(Error::UNKNOWN_AUDIO_FORMAT, path);
                        }
 
                        vorbis_info* vorbisInfo = ov_info(&mOggStream, -1);
@@ -110,7 +109,7 @@ public:
 
                void loadAll(ALuint source)
                {
-                       if (!mOggStream.datasource) openFile();
+                       if (!mOggStream.datasource) init(getName());
                        if (!mOggStream.datasource) return;
 
                        char data[BUFFER_SIZE];
@@ -180,7 +179,7 @@ public:
 
                void rewind()
                {
-                       if (!mOggStream.datasource) openFile();
+                       if (!mOggStream.datasource) init(getName());
                        else ov_raw_seek(&mOggStream, 0);
                }
 
@@ -207,6 +206,8 @@ public:
 
        void init()
        {
+               retainBackend();
+
                mIsLoaded = false;
                mIsPlaying = false;
                mIsLooping = false;
@@ -233,6 +234,8 @@ public:
                        alDeleteBuffers(1, &mBuffers.back());
                        mBuffers.pop_back();
                }
+
+               releaseBackend();
        }
 
 
@@ -426,6 +429,39 @@ public:
                // than a timer, probably as a compile-time option
        }
 
+       static void retainBackend()
+       {
+               if (gRetainCount++ == 0)
+               {
+                       gAlDevice = alcOpenDevice(0);
+                       gAlContext = alcCreateContext(gAlDevice, 0);
+                       if (!gAlDevice || !gAlContext)
+                       {
+                               const char* error = alcGetString(gAlDevice,
+                                               alcGetError(gAlDevice));
+                               logError << "audio subsystem initialization failure: "
+                                                << error << std::endl;
+                       }
+                       else
+                       {
+                               alcMakeContextCurrent(gAlContext);
+                               logInfo << "opened sound device `"
+                                               << alcGetString(gAlDevice, ALC_DEFAULT_DEVICE_SPECIFIER)
+                                               << "'" << std::endl;
+                       }
+               }
+       }
+
+       static void releaseBackend()
+       {
+               if (--gRetainCount == 0)
+               {
+                       alcMakeContextCurrent(0);
+                       alcDestroyContext(gAlContext);
+                       alcCloseDevice(gAlDevice);
+               }
+       }
+
 
        ALuint                                  mSource;
        std::list<ALuint>               mBuffers;
@@ -438,9 +474,15 @@ public:
 
        Timer                                   mStreamTimer;
 
-       Backend                                 mBackend;
+       static unsigned                 gRetainCount;
+       static ALCdevice*               gAlDevice;
+       static ALCcontext*              gAlContext;
 };
 
+unsigned       Sound::Impl::gRetainCount = 0;
+ALCdevice*     Sound::Impl::gAlDevice = 0;
+ALCcontext*    Sound::Impl::gAlContext = 0;
+
 
 Sound::Sound() :
        // pass through
@@ -550,8 +592,17 @@ void Sound::setListenerOrientation(const Vector3& forward, const Vector3& up)
 
 std::string Sound::getPath(const std::string& name)
 {
-       std::string path = Resource::getPath("sounds/" + name + ".ogg");
-       return path;
+       if (boost::find_last(name, ".ogg"))
+       {
+               return Resource::getPath(name);
+       }
+       else
+       {
+               std::string path("sounds/");
+               path += name;
+               path += ".ogg";
+               return Resource::getPath(path);
+       }
 }
 
 
This page took 0.022949 seconds and 4 git commands to generate.