Change Encyclo button name and macros icon
[ryzomcore.git] / nel / src / sound / background_source.cpp
blob013ace0736d14513bb3705b012dd061ad59b0303
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2010 Matt RAYKOWSKI (sfb) <matt.raykowski@gmail.com>
6 // Copyright (C) 2012 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 //
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as
10 // published by the Free Software Foundation, either version 3 of the
11 // License, or (at your option) any later version.
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 Affero General Public License for more details.
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "stdsound.h"
22 #include "nel/sound/background_sound_manager.h"
23 #include "nel/sound/background_source.h"
25 using namespace std;
26 using namespace NLMISC;
28 namespace NLSOUND
32 CBackgroundSource::CBackgroundSource(CBackgroundSound *backgroundSound, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster, CGroupController *groupController)
33 : CSourceCommon(backgroundSound, spawn, cb, cbUserParam, cluster, groupController)
35 _BackgroundSound = backgroundSound;
38 CBackgroundSource::~CBackgroundSource()
40 if (_Playing)
41 stop();
44 TSoundId CBackgroundSource::getSound()
46 return NULL;
49 void CBackgroundSource::setGain( float gain )
51 CSourceCommon::setGain(gain);
53 std::vector<TSubSource>::iterator first(_Sources.begin()), last(_Sources.end());
54 for (; first != last; ++first)
56 if (first->Source != 0)
58 first->Source->setGain(first->Source->getSound()->getGain() * gain);
59 first->Source->setRelativeGain(_Gain);
63 void CBackgroundSource::setRelativeGain( float gain )
65 CSourceCommon::setRelativeGain(gain);
67 std::vector<TSubSource>::iterator first(_Sources.begin()), last(_Sources.end());
68 for (; first != last; ++first)
70 if (first->Source != 0)
71 first->Source->setRelativeGain(_Gain);
75 void CBackgroundSource::setPos( const NLMISC::CVector& pos )
77 CSourceCommon::setPos(pos);
79 std::vector<TSubSource>::iterator first(_Sources.begin()), last(_Sources.end());
80 for (; first != last; ++first)
82 if (first->Source != 0)
83 first->Source->setPos(pos);
87 void CBackgroundSource::setVelocity( const NLMISC::CVector& vel )
89 CSourceCommon::setVelocity(vel);
91 std::vector<TSubSource>::iterator first(_Sources.begin()), last(_Sources.end());
92 for (; first != last; ++first)
94 if (first->Source != 0)
95 first->Source->setVelocity(vel);
98 void CBackgroundSource::setDirection( const NLMISC::CVector& dir )
100 CSourceCommon::setDirection(dir);
102 std::vector<TSubSource>::iterator first(_Sources.begin()), last(_Sources.end());
103 for (; first != last; ++first)
105 if (first->Source != 0)
106 first->Source->setDirection(dir);
112 void CBackgroundSource::play()
114 if (_Playing)
115 stop();
117 CAudioMixerUser *mixer = CAudioMixerUser::instance();
119 const vector<CBackgroundSound::TSoundInfo> &sounds = _BackgroundSound->getSounds();
120 vector<CBackgroundSound::TSoundInfo>::const_iterator first(sounds.begin()), last(sounds.end());
122 for (; first != last; ++first)
124 TSubSource subSource;
125 subSource.Source = mixer->createSource(first->SoundName, false, 0, 0, _Cluster, NULL, _GroupController);
126 if (subSource.Source != NULL)
127 subSource.Source->setPriority(_Priority);
128 subSource.Filter = first->Filter;
129 subSource.Status = SUB_STATUS_STOP;
130 _Sources.push_back(subSource);
133 updateFilterValues(mixer->getBackgroundSoundManager()->getFilterValues());
135 CSourceCommon::play();
138 void CBackgroundSource::stop()
140 if (_Playing)
142 while (!_Sources.empty())
144 TSubSource &subSource = _Sources.back();
145 if (subSource.Source != NULL)
147 delete subSource.Source;
149 _Sources.pop_back();
153 CSourceCommon::stop();
155 CAudioMixerUser::instance()->unregisterUpdate(this);
158 void CBackgroundSource::updateFilterValues(const float *filterValues)
160 bool needUpdate = false;
161 std::vector<TSubSource>::iterator first(_Sources.begin()), last(_Sources.end());
162 for (; first != last; ++first)
164 TSubSource &ss = *first;
165 if (ss.Source != 0)
167 float gain = 1.0f;
168 for (uint i=0; i<UAudioMixer::TBackgroundFlags::NB_BACKGROUND_FLAGS; ++i)
170 if (ss.Filter.Flags[i])
172 // this filter is used
173 gain *= filterValues[i];
177 if (gain == 0 && ss.Status != SUB_STATUS_STOP)
179 // need to completely stop the sound
180 if (ss.Source->isPlaying())
181 ss.Source->stop();
182 ss.Status = SUB_STATUS_STOP;
184 else if (gain > 0 && ss.Status != SUB_STATUS_PLAY)
186 // need to restard the sound
187 // ss.Source->setRelativeGain(gain * _Gain);
188 ss.Source->setGain(ss.Source->getSound()->getGain() * gain);
189 ss.Source->setRelativeGain(_Gain);
190 ss.Source->setPitch(ss.Source->getSound()->getPitch() * _Pitch);
191 ss.Source->setPos(_Position);
192 ss.Source->play();
193 // some sub sound can be too far from the listener,
194 // we must handle this in order to start them when the listener
195 // is closer
196 ss.Status = ss.Source->isPlaying() ? SUB_STATUS_PLAY : SUB_STATUS_PLAY_FAIL;
198 needUpdate |= (ss.Status == SUB_STATUS_PLAY_FAIL);
200 else //if (ss.Status == SUB_STATUS_PLAY)
202 // just update the gain
203 ss.Source->setGain(ss.Source->getSound()->getGain() * gain);
204 ss.Source->setRelativeGain(_Gain);
209 // if some some sub sound fail to play...
210 if (needUpdate)
211 CAudioMixerUser::instance()->registerUpdate(this);
215 void CBackgroundSource::onUpdate()
217 bool needUpdate = false;
218 // Some sub source are distance clipped, so retry to start them.
219 std::vector<TSubSource>::iterator first(_Sources.begin()), last(_Sources.end());
220 for (; first != last; ++first)
222 TSubSource &ss = *first;
223 if (ss.Status == SUB_STATUS_PLAY_FAIL)
225 ss.Source->play();
226 // some sub sound can be too far from the listener,
227 // we must handle this in order to start them when the listener
228 // is closer
229 ss.Status = ss.Source->isPlaying() ? SUB_STATUS_PLAY : SUB_STATUS_PLAY_FAIL;
231 needUpdate |= (ss.Status == SUB_STATUS_PLAY_FAIL);
235 // no more update needed ?
236 if (!needUpdate)
237 CAudioMixerUser::instance()->unregisterUpdate(this);
240 } // NLSOUND