Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core4/src/orxonox/sound/SoundManager.cc @ 4688

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

Fixed a bug in SoundManager: Construction, destruction and construction again failed due to a static variable that now is a member.

  • Property svn:eol-style set to native
File size: 5.5 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 "orxonox/CameraManager.h"
35#include "orxonox/objects/worldentities/Camera.h"
36#include "SoundBase.h"
37
38namespace orxonox
39{
40    SoundManager* SoundManager::singletonRef_s = NULL;
41
42    /**
43     * Default constructor
44     */
45    SoundManager::SoundManager()
46    {
47        assert(singletonRef_s == NULL);
48        singletonRef_s = this;
49
50        this->device_ = NULL;
51        this->soundavailable_ = true;
52        if(!alutInitWithoutContext(NULL,NULL))
53        {
54            COUT(2) << "Sound: OpenAL ALUT: " << alutGetErrorString(alutGetError()) << std::endl;
55            this->soundavailable_ = false;
56        }
57        else
58        {
59            assert(this->device_ == NULL);
60            COUT(3) << "Sound: OpenAL: Open sound device..." << std::endl;
61            this->device_ = alcOpenDevice(NULL);
62
63            if(this->device_ == NULL)
64            {
65                COUT(2) << "Sound: OpenAL: Could not open sound device" << std::endl;
66                this->soundavailable_ = false;
67            }
68            else
69            {
70                COUT(3) << "Sound: OpenAL: Sound device opened" << std::endl;
71                this->context_ = alcCreateContext(this->device_, NULL);
72                if(this->context_ == NULL)
73                {
74                    COUT(2) << "Sound: OpenAL: Could not create sound context" << std::endl;
75                    this->soundavailable_ = false;
76                }
77                else
78                {
79                    if(alcMakeContextCurrent(this->context_) == AL_TRUE)
80                        COUT(3) << "Sound: OpenAL: Context " << this->context_ << " loaded" << std::endl;
81
82                    COUT(4) << "Sound: OpenAL ALUT version: " << alutGetMajorVersion() << "." << alutGetMinorVersion() << std::endl;
83                    const char* str = alutGetMIMETypes(ALUT_LOADER_BUFFER);
84                    if (str == NULL)
85                        COUT(2) << "Sound: OpenAL ALUT: " << alutGetErrorString(alutGetError()) << std::endl;
86                    else
87                        COUT(4) << "Sound: OpenAL ALUT supported MIME types: " << str << std::endl;
88                }
89            }
90        }
91    }
92
93    SoundManager::~SoundManager()
94    {
95        assert(singletonRef_s != NULL);
96        singletonRef_s = NULL;
97
98        alcDestroyContext(this->context_);
99        alcCloseDevice(this->device_);
100        alutExit();
101    }
102
103    /**
104     * Add a SoundBase object to the list. Every SoundBase object should be in
105     * this list.
106     *
107     * @param sound Pointer to the SoundBase object to add
108     */
109    void SoundManager::addSound(SoundBase* sound)
110    {
111        this->soundlist_.push_back(sound);
112    }
113
114    /**
115     * Remove a SoundBase object from the list and destroy it.
116     */
117    void SoundManager::removeSound(SoundBase* sound)
118    {
119        std::list<SoundBase*>::iterator pos = this->soundlist_.end();
120        for(std::list<SoundBase*>::iterator i = this->soundlist_.begin(); i != this->soundlist_.end(); i++)
121        {
122            if((*i) == sound)
123                pos = i;
124        }
125
126        delete (*pos);
127        this->soundlist_.erase(pos);
128    }
129
130    /**
131     * Tick function, updates listener and registred SoundBase objects
132     *
133     * @param dt @see Orxonox::Tickable
134     */
135    void SoundManager::tick(float dt)
136    {
137        if (!CameraManager::getInstancePtr())
138            return;
139
140        // update listener position
141        Camera* camera = CameraManager::getInstance().getActiveCamera();
142        if(camera == NULL) return;
143        Vector3 pos = camera->getPosition();
144        alListener3f(AL_POSITION, pos.x, pos.y, pos.z);
145        ALenum error = alGetError();
146        if(error == AL_INVALID_VALUE)
147            COUT(2) << "Sound: OpenAL: Invalid listener position" << std::endl;
148
149        // update listener orientation
150        Quaternion orient = camera->getOrientation();
151        Vector3 up = orient.xAxis(); // just a wild guess
152        Vector3 at = orient.zAxis();
153
154        ALfloat orientation[6] = { at.x, at.y, at.z, 
155                                 up.x, up.y, up.z };
156
157        alListenerfv(AL_POSITION, orientation);
158        error = alGetError();
159        if(error == AL_INVALID_VALUE)
160            COUT(2) << "Sound: OpenAL: Invalid listener orientation" << std::endl;
161
162        // update sounds
163        for(std::list<SoundBase*>::iterator i = this->soundlist_.begin(); i != this->soundlist_.end(); i++)
164            (*i)->update();
165    }
166   
167    /**
168    * Check if sound is available
169    */
170    bool SoundManager::isSoundAvailable()
171    {
172        return this->soundavailable_;
173    }
174}
Note: See TracBrowser for help on using the repository browser.