Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core5/src/orxonox/sound/SoundManager.cc @ 5877

Last change on this file since 5877 was 5877, checked in by rgrieder, 15 years ago

Added new an option for the ScopedSingletonManager that can allow the Singleton to fail (throw an exception).
Also improved exception-safety in Scope so that when for a Singleton fails, the Scope will deactivate all activated listeners and properly destroy itself.

  • Property svn:eol-style set to native
File size: 5.4 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *       Erwin 'vaiursch' Herrsche
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "SoundManager.h"
30
31#include <AL/alut.h>
32
33#include "util/Math.h"
34#include "core/ScopedSingletonManager.h"
35#include "CameraManager.h"
36#include "graphics/Camera.h"
37#include "SoundBase.h"
38
39namespace orxonox
40{
41    SoundManager* SoundManager::singletonPtr_s = NULL;
42    ManageScopedSingleton(SoundManager, ScopeID::Graphics, true);
43
44    /**
45     * Default constructor
46     */
47    SoundManager::SoundManager()
48    {
49        this->device_ = NULL;
50        this->soundavailable_ = true;
51        if(!alutInitWithoutContext(NULL,NULL))
52        {
53            COUT(2) << "Sound: OpenAL ALUT: " << alutGetErrorString(alutGetError()) << std::endl;
54            this->soundavailable_ = false;
55        }
56        else
57        {
58            assert(this->device_ == NULL);
59            COUT(3) << "Sound: OpenAL: Open sound device..." << std::endl;
60            this->device_ = alcOpenDevice(NULL);
61
62            if(this->device_ == NULL)
63            {
64                COUT(2) << "Sound: OpenAL: Could not open sound device" << std::endl;
65                this->soundavailable_ = false;
66            }
67            else
68            {
69                COUT(3) << "Sound: OpenAL: Sound device opened" << std::endl;
70                this->context_ = alcCreateContext(this->device_, NULL);
71                if(this->context_ == NULL)
72                {
73                    COUT(2) << "Sound: OpenAL: Could not create sound context" << std::endl;
74                    this->soundavailable_ = false;
75                }
76                else
77                {
78                    if(alcMakeContextCurrent(this->context_) == AL_TRUE)
79                        COUT(3) << "Sound: OpenAL: Context " << this->context_ << " loaded" << std::endl;
80
81                    COUT(4) << "Sound: OpenAL ALUT version: " << alutGetMajorVersion() << "." << alutGetMinorVersion() << std::endl;
82                    const char* str = alutGetMIMETypes(ALUT_LOADER_BUFFER);
83                    if (str == NULL)
84                        COUT(2) << "Sound: OpenAL ALUT: " << alutGetErrorString(alutGetError()) << std::endl;
85                    else
86                        COUT(4) << "Sound: OpenAL ALUT supported MIME types: " << str << std::endl;
87                }
88            }
89        }
90    }
91
92    SoundManager::~SoundManager()
93    {
94        alcDestroyContext(this->context_);
95        alcCloseDevice(this->device_);
96        alutExit();
97    }
98
99    /**
100     * Add a SoundBase object to the list. Every SoundBase object should be in
101     * this list.
102     *
103     * @param sound Pointer to the SoundBase object to add
104     */
105    void SoundManager::addSound(SoundBase* sound)
106    {
107        this->soundlist_.push_back(sound);
108    }
109
110    /**
111     * Remove a SoundBase object from the list and destroy it.
112     */
113    void SoundManager::removeSound(SoundBase* sound)
114    {
115        std::list<SoundBase*>::iterator pos = this->soundlist_.end();
116        for(std::list<SoundBase*>::iterator i = this->soundlist_.begin(); i != this->soundlist_.end(); i++)
117        {
118            if((*i) == sound)
119                pos = i;
120        }
121
122        delete (*pos);
123        this->soundlist_.erase(pos);
124    }
125
126    /**
127     * Tick function, updates listener and registred SoundBase objects
128     *
129     * @param dt @see Orxonox::Tickable
130     */
131    void SoundManager::tick(float dt)
132    {
133        if (!CameraManager::getInstancePtr())
134            return;
135
136        // update listener position
137        Camera* camera = CameraManager::getInstance().getActiveCamera();
138        if(camera == NULL) return;
139        Vector3 pos = camera->getPosition();
140        alListener3f(AL_POSITION, pos.x, pos.y, pos.z);
141        ALenum error = alGetError();
142        if(error == AL_INVALID_VALUE)
143            COUT(2) << "Sound: OpenAL: Invalid listener position" << std::endl;
144
145        // update listener orientation
146        const Quaternion& orient = camera->getOrientation();
147        Vector3 up = orient.xAxis(); // just a wild guess
148        Vector3 at = orient.zAxis();
149
150        ALfloat orientation[6] = { at.x, at.y, at.z,
151                                 up.x, up.y, up.z };
152
153        alListenerfv(AL_POSITION, orientation);
154        error = alGetError();
155        if(error == AL_INVALID_VALUE)
156            COUT(2) << "Sound: OpenAL: Invalid listener orientation" << std::endl;
157
158        // update sounds
159        for(std::list<SoundBase*>::iterator i = this->soundlist_.begin(); i != this->soundlist_.end(); i++)
160            (*i)->update();
161    }
162
163    /**
164    * Check if sound is available
165    */
166    bool SoundManager::isSoundAvailable()
167    {
168        return this->soundavailable_;
169    }
170}
Note: See TracBrowser for help on using the repository browser.