1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2008-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
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
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/>.
22 #include "nel/sound/music_channel_fader.h"
25 #include "nel/sound/driver/sound_driver.h"
26 #include "nel/sound/driver/music_channel.h"
27 #include "nel/sound/source_music_channel.h"
30 using namespace NLMISC
;
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;
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();
64 nlwarning("No music channel available!");
71 void CMusicChannelFader::release()
75 for (uint i
= 0; i
< _MaxMusicFader
; ++i
) if (_MusicFader
[i
].MusicChannel
)
77 delete _MusicFader
[i
].MusicChannel
;
78 _MusicFader
[i
].MusicChannel
= 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
];
103 if (fader
.MusicChannel
->isEnded())
105 fader
.MusicChannel
->stop();
106 fader
.Playing
= false;
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
)
118 fader
.MusicChannel
->stop();
120 fader
.Playing
= false;
122 else if (fader
.XFadeVolume
>= 1.f
)
126 fader
.XFadeVolume
= 1.f
;
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
)
181 for (uint i
= 0; i
< _MaxMusicFader
; ++i
) if (_MusicFader
[i
].Playing
)
183 _MusicFader
[i
].fadeOut(xFadeTime
);
184 stopped
= false; // fading
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;
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
)
241 } /* namespace NLSOUND */