Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Added sound effects pooling. This should avoid long respawns (due to sound loading) if there are no more enemies.

  • Property svn:eol-style set to native
File size: 6.1 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            assert(this->audioSource_ != 0);
58        }
59    }
60
61    BaseSound::~BaseSound()
62    {
63        this->setSource("");
64        if (GameMode::playsSound())
65            alDeleteSources(1, &this->audioSource_);
66    }
67
68    void BaseSound::XMLPortExtern(Element& xmlelement, XMLPort::Mode mode)
69    {
70        XMLPortParam(BaseSound, "volume", setVolume,  getVolume,  xmlelement, mode);
71        XMLPortParam(BaseSound, "loop",   setLooping, getLooping, xmlelement, mode);
72        XMLPortParam(BaseSound, "play",   setPlaying, isPlaying,  xmlelement, mode);
73        XMLPortParam(BaseSound, "source", setSource,  getSource,  xmlelement, mode);
74    }
75
76    void BaseSound::play()
77    {
78        if (!this->isPlaying() && GameMode::showsGraphics())
79        {
80            this->state_ = Playing;
81            alSourcePlay(this->audioSource_);
82
83            if (int error = alGetError())
84                COUT(2) << "Sound: Error playing sound: " << error << std::endl;
85        }
86    }
87
88    void BaseSound::stop()
89    {
90        this->state_ = Stopped;
91        if (GameMode::playsSound())
92            alSourceStop(this->audioSource_);
93    }
94
95    void BaseSound::pause()
96    {
97        if (this->isStopped())
98            return;
99        this->state_ = Paused;
100        if (GameMode::playsSound())
101            alSourcePause(this->audioSource_);
102    }
103
104    void BaseSound::setVolume(float vol)
105    {
106        if (vol > 1 || vol < 0)
107        {
108            COUT(2) << "Sound warning: volume out of range, cropping value." << std::endl;
109            vol = vol > 1 ? 1 : vol;
110            vol = vol < 0 ? 0 : vol;
111        }
112        this->volume_ = vol;
113       
114        this->updateVolume();
115    }
116   
117    float BaseSound::getVolumeGain()
118    {
119        return SoundManager::getInstance().getVolume(SoundType::none);
120    }
121   
122    void BaseSound::updateVolume(void)
123    {
124        if (alIsSource(this->audioSource_))
125        {
126            alSourcef(this->audioSource_, AL_GAIN, this->volume_*this->getVolumeGain());
127            if (int error = alGetError())
128                COUT(2) << "Sound: Error setting volume: " << error << std::endl;
129        }
130    }
131
132    void BaseSound::setLooping(bool val)
133    {
134        this->bLoop_ = val;
135        if (GameMode::playsSound())
136            alSourcei(this->audioSource_, AL_LOOPING, (val ? AL_TRUE : AL_FALSE));
137    }
138
139    void BaseSound::setPitch(float pitch)
140    {
141        if (pitch > 2 || pitch < 0.5)
142        {
143            COUT(2) << "Sound warning: pitch out of range, cropping value." << std::endl;
144            pitch = pitch > 2 ? 2 : pitch;
145            pitch = pitch < 0.5 ? 0.5 : pitch;
146        }       
147        this->pitch_ = pitch;
148        if (GameMode::playsSound())
149        {
150            if (int error = alGetError())
151                COUT(2) << "Sound: Error setting pitch: " << error << std::endl;
152            alSourcef(this->audioSource_, AL_PITCH, pitch);
153        }
154    }
155
156    void BaseSound::setSource(const std::string& source)
157    {
158        if (!GameMode::playsSound() || source == this->source_) 
159        {
160            this->source_ = source;
161            return;
162        }
163
164        if (this->soundBuffer_ != NULL)
165        {
166            alSourceStop(this->audioSource_);
167            // Unload old sound first
168            alSourcei(this->audioSource_, AL_BUFFER, 0);
169            SoundManager::getInstance().releaseSoundBuffer(this->soundBuffer_, this->bPooling_);
170            this->soundBuffer_.reset();
171        }
172
173        this->source_ = source;
174        if (source_.empty())
175            return;
176
177        // Get DataStream from the resources
178        shared_ptr<ResourceInfo> fileInfo = Resource::getInfo(source);
179        if (fileInfo == NULL)
180        {
181            COUT(2) << "Sound: Warning: Sound file '" << source << "' not found" << std::endl;
182            return;
183        }
184
185        this->soundBuffer_ = SoundManager::getInstance().getSoundBuffer(fileInfo);
186        if (this->soundBuffer_ == NULL)
187            return;
188
189        alSourcei(this->audioSource_, AL_BUFFER, this->soundBuffer_->getBuffer());
190        if (alGetError() != AL_NO_ERROR)
191        {
192            COUT(2) << "Sound: OpenAL: Error loading sample file: " << source << std::endl;
193            return;
194        }
195
196        alSource3f(this->audioSource_, AL_POSITION,  0, 0, 0);
197        this->updateVolume();
198        this->setPitch(this->getPitch());
199        this->setLooping(getLooping());
200        if (this->isPlaying() || this->isPaused())
201        {
202            alSourcePlay(this->audioSource_);
203            if (int error = alGetError())
204                COUT(2) << "Sound: Error playing sound: " << error << std::endl;
205        }
206        if (this->isPaused())
207            alSourcePause(this->audioSource_);
208    }
209}
Note: See TracBrowser for help on using the repository browser.