]> Dogcows Code - chaz/yoink/blobdiff - src/Moof/Sound.cc
tcp socket disconnecting by remote
[chaz/yoink] / src / Moof / Sound.cc
index 3aec3f6aa90aa85f4c0f40936508a6ae01a2fff7..ffa270e9e9876768669cd7ca3bdf850d46b5b09c 100644 (file)
@@ -1,43 +1,28 @@
 
-/*******************************************************************************
-
- Copyright (c) 2009, Charles McGarvey
- All rights reserved.
- Redistribution   and   use  in  source  and  binary  forms,  with  or  without
- modification, are permitted provided that the following conditions are met:
-   * Redistributions  of  source  code  must retain the above copyright notice,
-     this list of conditions and the following disclaimer.
-   * Redistributions  in binary form must reproduce the above copyright notice,
-     this  list of conditions and the following disclaimer in the documentation
-     and/or other materials provided with the distribution.
- THIS  SOFTWARE  IS  PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND  ANY  EXPRESS  OR  IMPLIED  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED.  IN  NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES  (INCLUDING,  BUT  NOT  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- SERVICES;  LOSS  OF  USE,  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- OR  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-*******************************************************************************/
+/*]  Copyright (c) 2009-2010, Charles McGarvey  [**************************
+**]  All rights reserved.
+*
+* vi:ts=4 sw=4 tw=75
+*
+* Distributable under the terms and conditions of the 2-clause BSD license;
+* see the file COPYING for a complete text of the license.
+*
+**************************************************************************/
 
 #include <cstdio>
 #include <deque>
 #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 "Engine.hh"
-#include "Exception.hh"
-#include "Library.hh"
+#include "Error.hh"
+#include "Manager.hh"
 #include "Log.hh"
 #include "Sound.hh"
 #include "Timer.hh"
@@ -62,16 +47,14 @@ public:
        class Buffer;
        typedef boost::shared_ptr<Buffer> BufferP;
        
-       class Buffer : public Library<Buffer>
+       class Buffer : public Manager<Buffer>
        {
        public:
 
-               Buffer(const std::string& name) :
-                       Library<Buffer>(name),
+               Buffer() :
                        mBuffer(-1)
                {
                        mOggStream.datasource = 0;
-                       openFile();
                }
 
                ~Buffer()
@@ -84,7 +67,7 @@ public:
                }
 
 
-               void openFile()
+               void init(const std::string& name)
                {
                        if (mOggStream.datasource)
                        {
@@ -92,14 +75,15 @@ public:
                                mOggStream.datasource = 0;
                        }
 
-                       std::string filePath = Sound::getPath(getName());
-                       int result = ov_fopen((char*)filePath.c_str(), &mOggStream);
+                       std::string path(name);
+                       if (!Sound::getPath(path))
+                       {
+                               Error(Error::RESOURCE_NOT_FOUND, path).raise();
+                       }
 
-                       if (result < 0)
+                       if (ov_fopen((char*)path.c_str(), &mOggStream) < 0)
                        {
-                               logWarning("error while loading sound %s",
-                                               getName().c_str());
-                               throw Exception(ErrorCode::UNKNOWN_AUDIO_FORMAT, getName());
+                               Error(Error::UNKNOWN_AUDIO_FORMAT, path).raise();
                        }
 
                        vorbis_info* vorbisInfo = ov_info(&mOggStream, -1);
@@ -110,7 +94,7 @@ public:
 
                void loadAll(ALuint source)
                {
-                       if (!mOggStream.datasource) openFile();
+                       if (!mOggStream.datasource) init(getName());
                        if (!mOggStream.datasource) return;
 
                        char data[BUFFER_SIZE];
@@ -134,7 +118,8 @@ public:
                        }
                        if (size == 0)
                        {
-                               logWarning("decoded no bytes from %s", getName().c_str());
+                               logWarning << "decoded no bytes from "
+                                                  << getName() << std::endl;
                                return;
                        }
 
@@ -179,7 +164,7 @@ public:
 
                void rewind()
                {
-                       if (!mOggStream.datasource) openFile();
+                       if (!mOggStream.datasource) init(getName());
                        else ov_raw_seek(&mOggStream, 0);
                }
 
@@ -206,8 +191,7 @@ public:
 
        void init()
        {
-               // make sure the engine is initialized
-               Engine::getInstance();
+               retainBackend();
 
                mIsLoaded = false;
                mIsPlaying = false;
@@ -235,6 +219,8 @@ public:
                        alDeleteBuffers(1, &mBuffers.back());
                        mBuffers.pop_back();
                }
+
+               releaseBackend();
        }
 
 
@@ -337,7 +323,8 @@ public:
                                {
                                        // nothing more to play, stopping...
                                        mIsPlaying = false;
-                                       std::remove(mBuffers.begin(), mBuffers.end(), bufferObj);
+                                       std::remove(mBuffers.begin(), mBuffers.end(),
+                                                               bufferObj);
                                }
                        }
                }
@@ -345,8 +332,8 @@ public:
                ALenum state;
                alGetSourcei(mSource, AL_SOURCE_STATE, &state);
 
-               // restart playing if we're stopped but supposed to be playing... this
-               // means we didn't queue enough and the audio skipped :-(
+               // restart playing if we're stopped but supposed to be playing...
+               // this means we didn't queue enough and the audio skipped :-(
                if (mIsPlaying && state != AL_PLAYING)
                {
                        alSourcePlay(mSource);
@@ -424,8 +411,42 @@ public:
        {
                // don't let the music die!
                update();
-               // TODO - might be nice to also allow using threads for streaming rather
-               // than a timer, probably as a compile-time option
+               // TODO - might be nice to also allow using threads for streaming
+               // rather 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);
+               }
        }
 
 
@@ -439,8 +460,16 @@ public:
        std::deque<BufferP>             mQueue;
 
        Timer                                   mStreamTimer;
+
+       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
@@ -521,21 +550,18 @@ void Sound::setLooping(bool looping)
 
 void Sound::setListenerPosition(const Vector3& position)
 {
-       //alListener3f(AL_POSITION, float(position[0]), float(position[1]),
-                       //float(position[2]));
        float vec[] = {position[0], position[1], position[2]};
        alListenerfv(AL_POSITION, vec);
 }
 
 void Sound::setListenerVelocity(const Vector3& velocity)
 {
-       //alListener3f(AL_VELOCITY, float(velocity[0]), float(velocity[1]),
-                       //float(velocity[2]));
        float vec[] = {velocity[0], velocity[1], velocity[2]};
        alListenerfv(AL_VELOCITY, vec);
 }
 
-void Sound::setListenerOrientation(const Vector3& forward, const Vector3& up)
+void Sound::setListenerOrientation(const Vector3& forward,
+                                                                  const Vector3& up)
 {
        float vec[6];
        vec[0] = float(forward[0]);
@@ -548,14 +574,13 @@ void Sound::setListenerOrientation(const Vector3& forward, const Vector3& up)
 }
 
 
-std::string Sound::getPath(const std::string& name)
+bool Sound::getPath(std::string& name)
 {
-       std::string path = Resource::getPath("sounds/" + name + ".ogg");
-       return path;
+       return Resource::getPath(name, "sounds/", "ogg");
 }
 
 
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
 void SoundStream::enqueue(const std::string& name)
@@ -574,5 +599,3 @@ void SoundStream::play()
 
 } // namespace Mf
 
-/** vim: set ts=4 sw=4 tw=80: *************************************************/
-
This page took 0.026671 seconds and 4 git commands to generate.