Fix "no remove aqua speed" bug when player leaves the water
[ryzomcore.git] / nel / src / sound / music_channel_fader.cpp
blob3e1b0f1cf19942593314ba10cfde78f5d35ee975
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2008-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
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) 2010 Winch Gate Property Limited
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/music_channel_fader.h"
24 // Project includes
25 #include "nel/sound/driver/sound_driver.h"
26 #include "nel/sound/driver/music_channel.h"
27 #include "nel/sound/source_music_channel.h"
29 using namespace std;
30 using namespace NLMISC;
32 namespace NLSOUND {
34 CMusicChannelFader::CMusicChannelFader() : _SoundDriver(NULL), _ActiveMusicFader(0), _Gain(1.0f), _LastTime(0)
39 CMusicChannelFader::~CMusicChannelFader()
44 void CMusicChannelFader::init(ISoundDriver *soundDriver)
46 nlassert(!_SoundDriver);
47 _SoundDriver = soundDriver;
48 _ActiveMusicFader = 0;
49 _Gain = 1.0f;
50 _LastTime = CTime::getLocalTime();
51 for (uint i = 0; i < _MaxMusicFader; ++i)
53 nlassert(!_MusicFader[i].MusicChannel);
54 _MusicFader[i].MusicChannel = _SoundDriver->createMusicChannel();
55 if (!_MusicFader[i].MusicChannel)
57 if (_SoundDriver->getOption(ISoundDriver::OptionHasBufferStreaming))
59 _MusicFader[i].MusicChannel = new CSourceMusicChannel();
61 else
63 release();
64 nlwarning("No music channel available!");
65 return;
71 void CMusicChannelFader::release()
73 if (_SoundDriver)
75 for (uint i = 0; i < _MaxMusicFader; ++i) if (_MusicFader[i].MusicChannel)
77 delete _MusicFader[i].MusicChannel;
78 _MusicFader[i].MusicChannel = NULL;
80 _SoundDriver = NULL;
84 void CMusicChannelFader::reset()
86 for (uint i = 0; i < _MaxMusicFader; ++i) if (_MusicFader[i].MusicChannel)
88 if (_MusicFader[i].MusicChannel)
89 _MusicFader[i].MusicChannel->reset();
93 void CMusicChannelFader::update()
95 TTime current_time = CTime::getLocalTime();
96 float delta_time = (float)(current_time - _LastTime) / 1000.0f;
97 _LastTime = current_time;
98 for (uint i = 0; i < _MaxMusicFader; ++i)
100 _CMusicFader &fader = _MusicFader[i];
101 if (fader.Playing)
103 if (fader.MusicChannel->isEnded())
105 fader.MusicChannel->stop();
106 fader.Playing = false;
107 fader.Fade = false;
109 else if (fader.Fade)
111 // wait with fading in until the song has started playing (at 0 volume)
112 if (!fader.MusicChannel->isLoadingAsync())
114 fader.XFadeVolume += fader.XFadeDVolume * delta_time;
115 if (fader.XFadeVolume <= 0.f)
117 // fadeout complete
118 fader.MusicChannel->stop();
119 fader.Fade = false;
120 fader.Playing = false;
122 else if (fader.XFadeVolume >= 1.f)
124 // fadein complete
125 fader.Fade = false;
126 fader.XFadeVolume = 1.f;
132 updateVolume();
135 void CMusicChannelFader::updateVolume()
137 for (uint i = 0; i < _MaxMusicFader; ++i)
138 if (_MusicFader[i].Playing)
139 _MusicFader[i].MusicChannel->setVolume(_MusicFader[i].XFadeVolume * _Gain);
142 /** Play some music (.ogg etc...)
143 * NB: if an old music was played, it is first stop with stopMusic()
144 * \param filepath file path, CPath::lookup is done here
145 * \param async stream music from hard disk, preload in memory if false
146 * \param loop must be true to play the music in loop.
148 bool CMusicChannelFader::play(const std::string &filepath, uint xFadeTime, bool async, bool loop)
150 bool stopped = stop(xFadeTime);
152 // Find the next best free music channel
153 uint nextFader = _MaxMusicFader;
154 for (uint i = 0; i < _MaxMusicFader; ++i) if (!_MusicFader[i].Playing)
155 { nextFader = i; break; }
156 if (nextFader == _MaxMusicFader)
158 nextFader = (_ActiveMusicFader + 1) % _MaxMusicFader;
159 _MusicFader[nextFader].MusicChannel->stop();
160 _MusicFader[nextFader].Fade = false;
161 _MusicFader[nextFader].Playing = false;
163 _ActiveMusicFader = nextFader;
165 // Play a song in it :)
166 _CMusicFader &fader = _MusicFader[_ActiveMusicFader];
167 if (xFadeTime && !stopped) fader.fadeIn(xFadeTime); // only fade in when fading out
168 else fader.XFadeVolume = 1.0f;
169 fader.Playing = true;
170 updateVolume(); // make sure at ok volume to start :)
171 fader.Playing = fader.MusicChannel->play(filepath, async, loop);
172 return fader.Playing;
175 /// Stop the music previously loaded and played (the Memory is also freed)
176 bool CMusicChannelFader::stop(uint xFadeTime)
178 if (xFadeTime)
180 bool stopped = true;
181 for (uint i = 0; i < _MaxMusicFader; ++i) if (_MusicFader[i].Playing)
183 _MusicFader[i].fadeOut(xFadeTime);
184 stopped = false; // fading
186 return stopped;
188 else
190 for (uint i = 0; i < _MaxMusicFader; ++i) if (_MusicFader[i].Playing)
192 _MusicFader[i].MusicChannel->stop();
193 _MusicFader[i].Fade = false;
194 _MusicFader[i].Playing = false;
196 return true;
200 /// Pause the music previously loaded and played (the Memory is not freed)
201 void CMusicChannelFader::pause()
203 for (uint i = 0; i < _MaxMusicFader; ++i)
204 if (_MusicFader[i].Playing)
205 _MusicFader[i].MusicChannel->pause();
208 /// Resume the music previously paused
209 void CMusicChannelFader::resume()
211 for (uint i = 0; i < _MaxMusicFader; ++i)
212 if (_MusicFader[i].Playing)
213 _MusicFader[i].MusicChannel->resume();
216 /// Return true if all songs are finished.
217 bool CMusicChannelFader::isEnded()
219 for (uint i = 0; i < _MaxMusicFader; ++i)
221 if (_MusicFader[i].Playing) if (!_MusicFader[i].MusicChannel->isEnded())
222 return false; // at least one song still playing
224 return true; // no song found that is still playing
227 /// Return the total length (in second) of the music currently played
228 float CMusicChannelFader::getLength()
230 return _MusicFader[_ActiveMusicFader].MusicChannel->getLength();
233 /// Set the music volume (if any music played). (volume value inside [0 , 1]) (default: 1)
234 /// NB: the volume of music is NOT affected by IListener::setGain()
235 void CMusicChannelFader::setVolume(float gain)
237 _Gain = gain;
238 updateVolume();
241 } /* namespace NLSOUND */
243 /* end of file */