Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation2/src/orxonox/sound/BaseSound.cc @ 6260

Last change on this file since 6260 was 6260, checked in by rgrieder, 14 years ago

Audio sources seem to be very limited resources. If we create more than available sources (usually more than 256), it will not result in a failed assert anymore. Instead, the sound will simply not load and play.

  • Property svn:eol-style set to native
File size: 6.9 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 *      Reto Grieder
26 *
27 */
28
29#include "BaseSound.h"
30
31#include <cassert>
32#include <vector>
33#include <al.h>
34
35#include "core/CoreIncludes.h"
36#include "core/GameMode.h"
37#include "core/Resource.h"
38#include "core/XMLPort.h"
39#include "SoundBuffer.h"
40#include "SoundManager.h"
41
42namespace orxonox
43{
44    BaseSound::BaseSound()
45        : audioSource_(0)
46        , bPooling_(false)
47        , volume_(1.0)
48        , bLoop_(false)
49        , state_(Stopped)
50        , pitch_ (1.0)
51    {
52        RegisterRootObject(BaseSound);
53
54        if (GameMode::playsSound())
55        {
56            alGenSources(1, &this->audioSource_);
57            if (!alIsSource(this->audioSource_))
58                COUT(1) << "Sound: Source generation failed: " << SoundManager::getALErrorString(alGetError()) << std::endl;
59        }
60    }
61
62    BaseSound::~BaseSound()
63    {
64        this->setSource("");
65        if (GameMode::playsSound() && alIsSource(this->audioSource_))
66            alDeleteSources(1, &this->audioSource_);
67    }
68
69    void BaseSound::XMLPortExtern(Element& xmlelement, XMLPort::Mode mode)
70    {
71        XMLPortParam(BaseSound, "volume", setVolume,  getVolume,  xmlelement, mode);
72        XMLPortParam(BaseSound, "loop",   setLooping, getLooping, xmlelement, mode);
73        XMLPortParam(BaseSound, "play",   setPlaying, isPlaying,  xmlelement, mode);
74        XMLPortParam(BaseSound, "source", setSource,  getSource,  xmlelement, mode);
75    }
76
77    void BaseSound::play()
78    {
79        this->state_ = Playing;
80        if (GameMode::playsSound() && alIsSource(this->audioSource_) && this->getSourceState() != AL_PLAYING)
81        {
82            alSourcePlay(this->audioSource_);
83
84            if (int error = alGetError())
85                COUT(2) << "Sound: Error playing sound: " << error << std::endl;
86        }
87    }
88
89    void BaseSound::stop()
90    {
91        this->state_ = Stopped;
92        if (GameMode::playsSound() && alIsSource(this->audioSource_))
93            alSourceStop(this->audioSource_);
94    }
95
96    void BaseSound::pause()
97    {
98        if (this->isStopped())
99            return;
100        this->state_ = Paused;
101        if (GameMode::playsSound() && alIsSource(this->audioSource_))
102            alSourcePause(this->audioSource_);
103    }
104
105    ALint BaseSound::getSourceState() const
106    {
107        if (GameMode::playsSound() && alIsSource(this->audioSource_))
108        {
109            ALint state;
110            alGetSourcei(this->audioSource_, AL_SOURCE_STATE, &state);
111            return state;
112        }
113        else
114            return AL_INITIAL;
115    }
116
117    void BaseSound::setVolume(float vol)
118    {
119        if (vol > 1 || vol < 0)
120        {
121            COUT(2) << "Sound warning: volume out of range, cropping value." << std::endl;
122            vol = vol > 1 ? 1 : vol;
123            vol = vol < 0 ? 0 : vol;
124        }
125        this->volume_ = vol;
126       
127        this->updateVolume();
128    }
129   
130    float BaseSound::getVolumeGain()
131    {
132        return SoundManager::getInstance().getVolume(SoundType::none);
133    }
134   
135    void BaseSound::updateVolume(void)
136    {
137        if (alIsSource(this->audioSource_))
138        {
139            alSourcef(this->audioSource_, AL_GAIN, this->volume_*this->getVolumeGain());
140            if (int error = alGetError())
141                COUT(2) << "Sound: Error setting volume: " << error << std::endl;
142        }
143    }
144
145    void BaseSound::setLooping(bool val)
146    {
147        this->bLoop_ = val;
148        if (GameMode::playsSound() && alIsSource(this->audioSource_))
149            alSourcei(this->audioSource_, AL_LOOPING, (val ? AL_TRUE : AL_FALSE));
150    }
151
152    void BaseSound::setPitch(float pitch)
153    {
154        if (pitch > 2 || pitch < 0.5)
155        {
156            COUT(2) << "Sound warning: pitch out of range, cropping value." << std::endl;
157            pitch = pitch > 2 ? 2 : pitch;
158            pitch = pitch < 0.5 ? 0.5 : pitch;
159        }       
160        this->pitch_ = pitch;
161        if (GameMode::playsSound() && alIsSource(this->audioSource_))
162        {
163            if (int error = alGetError())
164                COUT(2) << "Sound: Error setting pitch: " << error << std::endl;
165            alSourcef(this->audioSource_, AL_PITCH, pitch);
166        }
167    }
168
169    void BaseSound::setSource(const std::string& source)
170    {
171        if (!GameMode::playsSound() || source == this->source_) 
172        {
173            this->source_ = source;
174            return;
175        }
176
177        if (this->soundBuffer_ != NULL)
178        {
179            if (alIsSource(this->audioSource_))
180            {
181                alSourceStop(this->audioSource_);
182                // Unload old buffer first
183                alSourcei(this->audioSource_, AL_BUFFER, 0);
184            }
185            SoundManager::getInstance().releaseSoundBuffer(this->soundBuffer_, this->bPooling_);
186            this->soundBuffer_.reset();
187        }
188
189        this->source_ = source;
190        if (source_.empty() || !alIsSource(this->audioSource_))
191            return;
192
193        // Get DataStream from the resources
194        shared_ptr<ResourceInfo> fileInfo = Resource::getInfo(source);
195        if (fileInfo == NULL)
196        {
197            COUT(2) << "Sound: Warning: Sound file '" << source << "' not found" << std::endl;
198            return;
199        }
200
201        this->soundBuffer_ = SoundManager::getInstance().getSoundBuffer(fileInfo);
202        if (this->soundBuffer_ == NULL)
203            return;
204
205        alSourcei(this->audioSource_, AL_BUFFER, this->soundBuffer_->getBuffer());
206        if (ALuint error = alGetError())
207        {
208            COUT(1) << "Sound Error: Could not load file \"" << source << "\": " << SoundManager::getALErrorString << std::endl;
209            return;
210        }
211
212        alSource3f(this->audioSource_, AL_POSITION,  0, 0, 0);
213        this->updateVolume();
214        this->setPitch(this->getPitch());
215        this->setLooping(getLooping());
216        if (this->isPlaying() || this->isPaused())
217        {
218            alSourcePlay(this->audioSource_);
219            if (int error = alGetError())
220                COUT(2) << "Sound: Error playing sound: " << error << std::endl;
221        }
222        if (this->isPaused())
223            alSourcePause(this->audioSource_);
224    }
225}
Note: See TracBrowser for help on using the repository browser.