Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/sound3/src/orxonox/sound/SoundManager.cc @ 6031

Last change on this file since 6031 was 6031, checked in by youngk, 15 years ago

Implemented automatic ambient sound file path fetch according to current mood.
Valid moods are: default and dnb
BUG Loading of a second sound fails (independent of the file used). Probably an error in BaseSound::setSource().

  • Property svn:eol-style set to native
File size: 5.8 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/Exception.h"
34#include "util/Math.h"
35#include "util/ScopeGuard.h"
36#include "util/StringUtils.h"
37#include "core/GameMode.h"
38#include "core/ScopedSingletonManager.h"
39#include "core/Resource.h"
40#include "BaseSound.h"
41#include "MoodManager.h"
42
43namespace orxonox
44{
45    SoundManager* SoundManager::singletonPtr_s = NULL;
46    ManageScopedSingleton(SoundManager, ScopeID::Graphics, true);
47
48    SoundManager::SoundManager()
49    {
50        if (!alutInitWithoutContext(NULL,NULL))
51            ThrowException(InitialisationFailed, "Sound: OpenAL ALUT error: " << alutGetErrorString(alutGetError()));
52        Loki::ScopeGuard alutExitGuard = Loki::MakeGuard(&alutExit);
53
54        COUT(3) << "Sound: OpenAL: Opening sound device..." << std::endl;
55        this->device_ = alcOpenDevice(NULL);
56        if (this->device_ == NULL)
57        {
58            COUT(0) << "Sound: OpenaAL: Could not open sound device. Have you installed OpenAL?" << std::endl;
59#ifdef ORXONOX_PLATFORM_WINDOWS
60            COUT(0) << "Sound: Just getting the DLL with the dependencies is not enough for Windows (esp. Windows 7)!" << std::endl;
61#endif
62            ThrowException(InitialisationFailed, "Sound: OpenAL error: Could not open sound device.");
63        }
64        Loki::ScopeGuard closeDeviceGuard = Loki::MakeGuard(&alcCloseDevice, this->device_);
65
66        COUT(3) << "Sound: OpenAL: Sound device opened" << std::endl;
67        this->context_ = alcCreateContext(this->device_, NULL);
68        if (this->context_ == NULL)
69            ThrowException(InitialisationFailed, "Sound: OpenAL error: Could not create sound context");
70        Loki::ScopeGuard desroyContextGuard = Loki::MakeGuard(&alcDestroyContext, this->context_);
71
72        if (alcMakeContextCurrent(this->context_) == AL_TRUE)
73            COUT(3) << "Sound: OpenAL: Context " << this->context_ << " loaded" << std::endl;
74
75        COUT(4) << "Sound: OpenAL ALUT version: " << alutGetMajorVersion() << "." << alutGetMinorVersion() << std::endl;
76
77        const char* str = alutGetMIMETypes(ALUT_LOADER_BUFFER);
78        if (str == NULL)
79            COUT(2) << "Sound: OpenAL ALUT error: " << alutGetErrorString(alutGetError()) << std::endl;
80        else
81            COUT(4) << "Sound: OpenAL ALUT supported MIME types: " << str << std::endl;
82
83        GameMode::setPlaysSound(true);
84        // Disarm guards
85        alutExitGuard.Dismiss();
86        closeDeviceGuard.Dismiss();
87        desroyContextGuard.Dismiss();
88    }
89
90    SoundManager::~SoundManager()
91    {
92        GameMode::setPlaysSound(false);
93        alcDestroyContext(this->context_);
94        alcCloseDevice(this->device_);
95        alutExit();
96    }
97
98    void SoundManager::setListenerPosition(const Vector3& position)
99    {
100        alListener3f(AL_POSITION, position.x, position.y, position.z);
101        ALenum error = alGetError();
102        if (error == AL_INVALID_VALUE)
103            COUT(2) << "Sound: OpenAL: Invalid listener position" << std::endl;
104    }
105
106    void SoundManager::setListenerOrientation(const Quaternion& orientation)
107    {
108        // update listener orientation
109        Vector3 up = orientation.xAxis(); // just a wild guess
110        Vector3 at = orientation.zAxis();
111
112        ALfloat orient[6] = { at.x, at.y, at.z,
113                              up.x, up.y, up.z };
114
115        alListenerfv(AL_POSITION, orient);
116        ALenum error = alGetError();
117        if (error == AL_INVALID_VALUE)
118            COUT(2) << "Sound: OpenAL: Invalid listener orientation" << std::endl;
119    }
120
121    void SoundManager::registerAmbientSound(BaseSound* newAmbient)
122    {
123        if (!(this->ambientSounds_.empty())) 
124        {
125            this->ambientSounds_.front()->pause();
126        }
127        this->ambientSounds_.push_front(newAmbient);
128    }
129
130    void SoundManager::unregisterAmbientSound(BaseSound* currentAmbient)
131    {
132        if(currentAmbient == NULL || ambientSounds_.empty())
133        {
134            return;
135        }
136        if(this->ambientSounds_.front() == currentAmbient) 
137        {
138            this->ambientSounds_.pop_front();
139            if(!(this->ambientSounds_.empty()))
140            {
141                this->ambientSounds_.front()->replay();
142            }
143        }
144        else
145        {
146            for(std::list<BaseSound*>::iterator it= this->ambientSounds_.begin(); it != this->ambientSounds_.end(); it++)
147            {
148                if(*it == currentAmbient)
149                {
150                    this->ambientSounds_.erase(it);
151                    break;
152                }
153            }
154        }
155    }
156
157    // Get the current mood and return the full path string to the requested sound.
158    const std::string& SoundManager::getAmbientPath(const std::string& source)
159    {
160        lastReqPath = "ambient/" + MoodManager::getInstance().getMood() + "/" + source;
161        shared_ptr<ResourceInfo> fileInfo = Resource::getInfo(lastReqPath);
162        if(fileInfo == NULL)
163        {
164            return BLANKSTRING;
165        }
166        return lastReqPath;
167    }
168}
Note: See TracBrowser for help on using the repository browser.